I have a library that I am required to use that has a dangerous initialization of a static value (the classes have been stripped down to the minimum for the example):
public TheirBaseClass {
public static String PathToUse = null;
public BaseClass(){
PathToUse = "Configured";
// ...
// do some other stuff with other side effects
// ...
}
}
I have a case where I attempt to read from the value ConfigValue without instantiating the class (to avoid some of the sideeffects).
Paths.get(TheirBaseClass.PathToUse).toFile()....
This causes a NullPointerException
Because I am required to use this class, I am looking to inherit from it, and attempt to take action to ensure that initialization has taken place when accessing the static.
public MyBaseClass extends TheirBaseClass{
private static final AtomicBoolean isInitialized = new AtomicBoolean(false);
static {
MyBaseClass.Initialize();
}
public static void Initialize(){
// FindBugs does not like me synchronizing on a concurrent object
synchronized(isInitialized){
if( isInitialized.get() ){
return;
}
new TheirBaseClass();
isInitialized.set(true);
}
}
public MyBaseClass(){
super();
}
}
Which allows me to
MyBaseClass.Initialize();
Paths.get(MyBaseClass.PathToUse).toFile()....
This seems to be working reasonably well (and resolves some other phantom defects we've been having). It allows TheirBaseClass to function naturally, while allowing me to safely force initialization in the couple of cases I may need to.
However when I run FindBugs against this code, I get JLM_JSR166_UTILCONCURRENT_MONITORENTER. After reading the description, I agree that the use of AtomicBoolean could be dangerous because someone else could change the value, but...
I think its safe to ignore in this case (but have a doubt)
I generally prefer to rewrite code than put an ignore marker in place
Am I actually doing something dangerous (and just don't see it)? Is there a better way to do this?
Unfortunately, using a different TheirBaseClass is not an option.
Related
Are Java static initializers thread safe?
You might find it easier to adapt the lazy holder idiom:
public MyBaseClass {
private static class Initializer {
static {
new TheirBaseClass();
}
// Doesn't actually do anything; merely provides an expression
// to cause the Initializer class to be loaded.
private static void ensureInitialized() {}
}
{
Initializer.ensureInitialized();
}
// Rest of the class.
}
This uses the fact that class loading happens only once and is synchronized (within a single class loader). It happens only when you instantiate a MyBaseClass.
I have a singleton class
public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}}
And TextReader constructor that could throw FileNameEception
public TextReader(String filename) throws FileNameException{
if(!filename.matches("[A-Za-z0-9]*\\.txt"))
throw new FileNameException("Wrong file name!");
file = new File(filename);
}
How can I rethrow it to main and catch it there?
Main class
public class TextRunner {
public static void main(String[] args) {
// write your code here
SingletonText.getInstance().parse();
System.out.println("Parsed text:\n");
SingletonText.getInstance().print();
System.out.println("\n\n(Var8)Task1:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
System.out.println("\n\n(Var9)Task2:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
System.out.println("\n\n(Var16)Task3:");
String result = SubStringReplace.replace(SingletonText.getInstance()
.searchSentence(".*IfElseDemo.*"), 3, "EPAM");
System.out.println(result);
}}
Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.
In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What #Alexander Pogrebnyak has said is also true.
Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:
you need to create a singleton object of your CompositeText class.
create a setter method will create an object TextReader class using the file name string passed.
that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.
P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.
Code:
public class SingletonText {
private static CompositeText text = null;
static{
try {
text = new CompositeText(new TextReader("text/text.txt").readFile());
} catch (FileNameException e) {
// TODO: re-throw whatever you want
}
}
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}
}
try to lazy initialze the singleton.
something like this:
public class SingletonText {
private static CompositeText text;
public SingletonText() {
}
public static CompositeText getInstance() {
if (text ==null) {
text = new CompositeText(new TextReader("text/text.txt").readFile());
}
return text;
}
}
Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki:
https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Enjoy..
You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.
As a cause it will have your FileNameException.
If you don't do anything, default exception handler will print the whole stack trace to standard error.
I am having a difficult time understanding the way static classes are using in the following scenario.
Let’s say I declare a class as follows:
public class TestLibrary {
private static final TestLibrary library = new TestLibrary();
private ErrorHandler errorHandler = null;
public static TestLibrary getLibrary() {
return library;
}
public ErrorHandler getErrorHandler() {
return errorHandler;
}
public int run(String[] args) {
this.initialize(args);
}
private void initialize(String[] data) {
library.errorHandler = new ErrorHandler();
}
}
I now change the class slightly to
private void initialize(String[] data) {
errorHandler = new ErrorHandler();
}
I declare errorHandler in other classes as follows:
private ErrorHandler errorHandler = TestLibrary.getLibrary().getErrorHandler();
My code ultimately still functions the same when I use the instance of errorHandler in other classes, but I don’t understand why.
Question 1: Shouldn’t the 2nd case create a new ErrorHandler that is part of the object TestLibrary.errorHandler rather than library.errorHandler?
Question 2: Am I doing something wrong? Could you elaborate?
What you have there is a static method getLibrary() that returns the same instance for all callers. That's called a Singleton - although there's better ways to code them.
Then again your supposed Singleton (TestLibrary) exhibits methods that when called change internal state - most important, the ErrorHandler.
This will cause strange behaviour, especially in multithreaded systems.
Code like this:
TestLibrary.getLibrary().run("".split(""));
ErrorHandler eh = TestLibrary.getErrorHandler();
assertEquals(eh, TestLibrary.getErrorHandler());
might fail. Because someone (meaning: some other thread) might have just happend to call init() between lines 2 and 3, causing ErrorHandler to be set to just another value.
If you need to initialize your TestLibrary before use, you should do it once, and once only - so you're better of putting this into the constructor of TestLibrary.
If you need TestLibraries that are intialized different throughout your code, you should remove the Singleton pattern and stick to plain
TestLibrary tl = new TestLibrary();
tl.run("".split(""));
Read more about Singleton in What is an efficient way to implement a singleton pattern in Java?
I want to run a CompletableFuture property on a given class. If i have initialized like so, would that be dangerous and possibly create a partially constructed object?
public class MyClass {
public final CompletableFuture<BigDecimal> myExpensiveVal = CompletableFuture.supplyASync(() -> calculateExpensiveMethod(this));
//...
}
CompletableFuture.supplyASync sends the provided Supplier to another thread and, of course, if this supplier has any reference to your instance under construction, it is a leakage of this which makes an incomplete object instance visible to other threads and even voids any final publication guaranty.
In this special case it’s so obvious that you can spot this escaping reproducibly:
public class EscapingThis {
public final CompletableFuture<BigDecimal> myExpensiveVal
= CompletableFuture.supplyAsync(() -> calculateExpensiveMethod(this));
final int fourtyTwo;
public EscapingThis() {
System.out.println(Thread.currentThread()+" starts creating "+this);
try {
myExpensiveVal.get();
} catch (InterruptedException|ExecutionException ex) {
Logger.getLogger("EscapingThis").log(Level.SEVERE, null, ex);
}
System.out.println("still incomplete");
fourtyTwo=42;
System.out.println("leaving constructor");
}
static BigDecimal calculateExpensiveMethod(EscapingThis instance) {
System.out.println(Thread.currentThread()
+" says: hello incomplete instance "+instance);
System.out.println("fourtyTwo = "+instance.fourtyTwo);
return BigDecimal.ONE;
}
public static void main(String... arg) {
new EscapingThis();
}
}
Here you will see hello incomplete instance EscapingThis#1a9515 and fourtyTwo = 0 before still incomplete and leaving constructor for sure. But you might even see the Thread[main,5,main] starts creating … message after the hello incomplete … message as the timing is undefined.
Note that if calculateExpensiveMethod is an instance method, it doesn’t need the this parameter to let the instance leak. The implied reference to this on which the instance method will be invoked is also a leaking reference.
What is the preferred way to work with Singleton class in multithreaded environment?
Suppose if I have 3 threads, and all of them try to access getInstance() method of singleton class at the same time -
What would happen if no synchronization is maintained?
Is it good practice to use synchronized getInstance() method or use synchronized block inside getInstance().
Please advise if there is any other way out.
If you're talking about threadsafe, lazy initialization of the singleton, here is a cool code pattern to use that accomplishes 100% threadsafe lazy initialization without any synchronization code:
public class MySingleton {
private static class MyWrapper {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return MyWrapper.INSTANCE;
}
}
This will instantiate the singleton only when getInstance() is called, and it's 100% threadsafe! It's a classic.
It works because the class loader has its own synchronization for handling static initialization of classes: You are guaranteed that all static initialization has completed before the class is used, and in this code the class is only used within the getInstance() method, so that's when the class loaded loads the inner class.
As an aside, I look forward to the day when a #Singleton annotation exists that handles such issues.
Edited:
A particular disbeliever has claimed that the wrapper class "does nothing". Here is proof that it does matter, albeit under special circumstances.
The basic difference is that with the wrapper class version, the singleton instance is created when the wrapper class is loaded, which when the first call the getInstance() is made, but with the non-wrapped version - ie a simple static initialization - the instance is created when the main class is loaded.
If you have only simple invocation of the getInstance() method, then there is almost no difference - the difference would be that all other sttic initialization would have completed before the instance is created when using the wrapped version, but this is easily dealt with by simply having the static instance variable listed last in the source.
However, if you are loading the class by name, the story is quite different. Invoking Class.forName(className) on a class cuasing static initialization to occur, so if the singleton class to be used is a property of your server, with the simple version the static instance will be created when Class.forName() is called, not when getInstance() is called. I admit this is a little contrived, as you need to use reflection to get the instance, but nevertheless here's some complete working code that demonstrates my contention (each of the following classes is a top-level class):
public abstract class BaseSingleton {
private long createdAt = System.currentTimeMillis();
public String toString() {
return getClass().getSimpleName() + " was created " + (System.currentTimeMillis() - createdAt) + " ms ago";
}
}
public class EagerSingleton extends BaseSingleton {
private static final EagerSingleton INSTANCE = new EagerSingleton();
public static EagerSingleton getInstance() {
return INSTANCE;
}
}
public class LazySingleton extends BaseSingleton {
private static class Loader {
static final LazySingleton INSTANCE = new LazySingleton();
}
public static LazySingleton getInstance() {
return Loader.INSTANCE;
}
}
And the main:
public static void main(String[] args) throws Exception {
// Load the class - assume the name comes from a system property etc
Class<? extends BaseSingleton> lazyClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.LazySingleton");
Class<? extends BaseSingleton> eagerClazz = (Class<? extends BaseSingleton>) Class.forName("com.mypackage.EagerSingleton");
Thread.sleep(1000); // Introduce some delay between loading class and calling getInstance()
// Invoke the getInstace method on the class
BaseSingleton lazySingleton = (BaseSingleton) lazyClazz.getMethod("getInstance").invoke(lazyClazz);
BaseSingleton eagerSingleton = (BaseSingleton) eagerClazz.getMethod("getInstance").invoke(eagerClazz);
System.out.println(lazySingleton);
System.out.println(eagerSingleton);
}
Output:
LazySingleton was created 0 ms ago
EagerSingleton was created 1001 ms ago
As you can see, the non-wrapped, simple implementation is created when Class.forName() is called, which may be before the static initialization is ready to be executed.
The task is non-trivial in theory, given that you want to make it truly thread safe.
A very nice paper on the matter is found # IBM
Just getting the singleton does not need any sync, since it's just a read. So, just synchronize the setting of the Sync would do. Unless two treads try to create the singleton at start up at the same time, then you need to make sure check if the instance is set twice (one outside and one inside the sync) to avoid resetting the instance in a worst case scenario.
Then you might need to take into account how JIT (Just-in-time) compilers handle out-of-order writes. This code will be somewhat near the solution, although won't be 100% thread safe anyway:
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) {
Singleton inst = instance;
if (inst == null) {
synchronized(Singleton.class) {
instance = new Singleton();
}
}
}
}
return instance;
}
So, you should perhaps resort to something less lazy:
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
Or, a bit more bloated, but a more flexible way is to avoid using static singletons and use an injection framework such as Spring to manage instantiation of "singleton-ish" objects (and you can configure lazy initialization).
You need synchronization inside getInstance only if you initialize your singleton lazily. If you could create an instance before the threads are started, you can drop synchronization in the getter, because the reference becomes immutable. Of course if the singleton object itself is mutable, you would need to synchronize its methods which access information that can be changed concurrently.
This question really depends on how and when your instance is created. If your getInstance method lazily initializes:
if(instance == null){
instance = new Instance();
}
return instance
Then you must synchronize or you could end up with multiple instances. This problem is usually treated in talks on Double Checked Locking.
Otherwise if you create a static instance up front
private static Instance INSTANCE = new Instance();
then no synchronization of the getInstance() method is necessary.
The best way as described in effective java is:
public class Singelton {
private static final Singelton singleObject = new Singelton();
public Singelton getInstance(){
return singleObject;
}
}
No need of synchronization.
Nobody uses Enums as suggested in Effective Java?
If you are sure that your java runtime is using the new JMM (Java memory model, probably newer than 5.0), double check lock is just fine, but add a volatile in front of instance. Otherwise, you'd better use static internal class as Bohemian said, or Enum in 'Effective Java' as Florian Salihovic said.
For simplicity, I think using enum class is a better way. We don't need to do any synchronization. Java by construct, always ensure that there is only one constant created, no matter how many threads are trying to access it.
FYI, In some case you need to swap out singleton with other implementation. Then we need to modify class, which is violation of Open Close principal.Problem with singleton is, you can't extend the class because of having private constructor. So, it's a better practice that client is talking via interface.
Implementation of Singleton with enum class and Interface:
Client.java
public class Client{
public static void main(String args[]){
SingletonIface instance = EnumSingleton.INSTANCE;
instance.operationOnInstance("1");
}
}
SingletonIface.java
public interface SingletonIface {
public void operationOnInstance(String newState);
}
EnumSingleton.java
public enum EnumSingleton implements SingletonIface{
INSTANCE;
#Override
public void operationOnInstance(String newState) {
System.out.println("I am Enum based Singleton");
}
}
The Answer is already accepted here, But i would like to share the test to answer your 1st question.
What would happen if no synchronization is maintained?
Here is the SingletonTest class which will be completely disaster when you run in multi Threaded Environment.
/**
* #author MILAN
*/
public class SingletonTest
{
private static final int PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors();
private static final Thread[] THREADS = new Thread[PROCESSOR_COUNT];
private static int instancesCount = 0;
private static SingletonTest instance = null;
/**
* private constructor to prevent Creation of Object from Outside of the
* This class.
*/
private SingletonTest()
{
}
/**
* return the instance only if it does not exist
*/
public static SingletonTest getInstance()
{
if (instance == null)
{
instancesCount++;
instance = new SingletonTest();
}
return instance;
}
/**
* reset instancesCount and instance.
*/
private static void reset()
{
instancesCount = 0;
instance = null;
}
/**
* validate system to run the test
*/
private static void validate()
{
if (SingletonTest.PROCESSOR_COUNT < 2)
{
System.out.print("PROCESSOR_COUNT Must be >= 2 to Run the test.");
System.exit(0);
}
}
public static void main(String... args)
{
validate();
System.out.printf("Summary :: PROCESSOR_COUNT %s, Running Test with %s of Threads. %n", PROCESSOR_COUNT, PROCESSOR_COUNT);
long currentMili = System.currentTimeMillis();
int testCount = 0;
do
{
reset();
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i] = new Thread(SingletonTest::getInstance);
for (int i = 0; i < PROCESSOR_COUNT; i++)
THREADS[i].start();
for (int i = 0; i < PROCESSOR_COUNT; i++)
try
{
THREADS[i].join();
}
catch (InterruptedException e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
testCount++;
}
while (instancesCount <= 1 && testCount < Integer.MAX_VALUE);
System.out.printf("Singleton Pattern is broken after %d try. %nNumber of instances count is %d. %nTest duration %dms", testCount, instancesCount, System.currentTimeMillis() - currentMili);
}
}
Output of the program is clearly shows that you need handle this using getInstance as synchronized or add synchronized lock enclosing new SingletonTest.
Summary :: PROCESSOR_COUNT 32, Running Test with 32 of Threads.
Singleton Pattern is broken after 133 try.
Number of instance count is 30.
Test duration 500ms