Is instantiating an instance of SynchroClass as defined below and calling sCMethod going to cause a deadlock when the second sCMethod tries to get a lock on lockObject?
SO suggests I might mean something like Re-entrancy in Java saves us from a deadlock situation in this code sample.. How, why?, which seems to suggest that it is not a deadlock as the same object already has the lock ownership, but that talks about synchronized methods, so is at least a little different.
class SynchroClass {
static Object lockObject = new Object();
private boolean otherCondition = true;
public boolean sCMethod(boolean condition) {
synchronized(lockObject) {
if(condition) {
// some code
} else if(otherCondition) {
// some code
sCMethod(false);
// some code
} else {
// some code
}
return true;
}
}
}
Related
This question already has answers here:
What is an efficient way to implement a singleton pattern in Java? [closed]
(29 answers)
Closed 5 years ago.
As we know for synchronous operation while creating singleton class we make whole method as synchronized or only block of statements which are responsible for creation of object as synchronized.But, among these two approaches which one is better and why?
Approach 1
public static A getA(){
if (obj == null){
synchronized(Singleton.class) {
if (obj == null) {
obj = new Singleton();//instance will be created at request time
}
}
}
return obj;
}
Approach 2
public synchronized static A getA(){
if (obj == null){
obj = new Singleton();//instance will be created at request time
}
return obj;
}
Concept:
public synchronized static A getA(){
if (obj == null){
obj = new Singleton();//instance will be created at request time
}
return obj;
}
Using the synchronization keyword on a method (like in the example above) synchronizes access to that entire method, which is generally pretty safe but unless you have a very small method you may be synchronizing a bigger chunk of code than you absolutely need to, which is more of a performance hit than necessary. Because synchronized blocks/methods can only be accessed by one thread at a time, they really slow down processing. The larger a chunk of code you synchronize, the worse the performance hit is.
If you require only a single resource that is lazy loaded, you need to do something like this:
class MyClass {
private static volatile Resource resource;
private static final Object LOCK = new Object();
public static Resource getInstance() {
if(resource == null) {
synchronized(LOCK) { // Add a synch block
if(resource == null) { // verify some other synch block didn't
// write a resource yet...
resource = new Resource();
}
}
}
return resource;
}
}
One important thing here is the volatile modifier providing visibility for the whole threads in your app.
The first one is better because you don't acquire the lock when obj is not null, while the second approach acquires the lock each time.
I would take the first one, which has a double checked locking.
Maybe you can also try something like this:
public class MySingleton {
private static instance = new MySingleton ();
private MySingleton (){ }
public MySingleton getInstance {
return instance;
}
}
You'd better use Holder idiom
public class HolderFactory {
public static Singleton get() {
return Holder.instance;
}
private static class Holder {
public static final Singleton instance = new Singleton();
}
}
It is lazy because instance will be created upon first call to get() and it is thread-safe because class is guaranteed to be loaded by classloader in a single thread.
You could also check this link for more details regarding singletons and thread-safety: https://shipilev.net/blog/2014/safe-public-construction/
I wrote a small class that blocks in a method if the value is null. For some reason, it is throwing a StackOverflowError, what I am doing wrong?
public class BlockingObjectProperty<T> extends SimpleObjectProperty<T> {
public T get() {
if (super.get() == null) {
addListener(((observableValue, t, t1) -> {
synchronized (this) {
notifyAll();
}
}));
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
return super.get();
}
}
Here is my test code:
BlockingObjectProperty<String> blockingObjectProperty = new BlockingObjectProperty<String>();
new Thread(){
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
blockingObjectProperty.set("hello world");
}
}.start();
System.out.println(blockingObjectProperty.get());
And here is a snippet of the exception:
Exception in thread "main" java.lang.StackOverflowError
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
at javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:50)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:152)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.<init>(ExpressionHelper.java:144)
at com.sun.javafx.binding.ExpressionHelper.addListener(ExpressionHelper.java:69)
at javafx.beans.property.ObjectPropertyBase.addListener(ObjectPropertyBase.java:87)
at com.neonorb.commons.property.BlockingObjectProperty.get(BlockingObjectProperty.java:8)
When you call addListener JavaFX asks the property for its current value (in ExpressionHelper.java:152), calling getValue() again. Then - since the value is still null - you add another listener and so on ad infinitum.
If you want to wait for some variable to become non-null:
private final Object myVarLock = new Object();
private MyType myVar;
MyType get_myVar() {
synchronized(myVarLock) {
while (myVar == NULL) {
myVarLock.wait();
}
return myVar;
}
}
And to set the variable:
void set_myVar(myType newValue) {
synchronized(myVarLock) {
myVar = newValue;
myVarLock.notifyAll();
}
}
NOTES
The getter waits in a loop. This is necessary for strict correctness because the Java Langauge Spec allows wait() to return even when it has not been notified. (a.k.a., spurious wakeup).
Even if spurious wakeups don't happen in your JVM or in your application, it still is smart to always use a loop. The loop is essential in any algorithm where multiple consumer threads compete with one another to receive events. The loop doesn't cost any more than an if, so you might as well just be in the habit of always using the loop.
The test of myVar and the assignment of myVar both are inside the synchronized blocks. This is important. If they weren't both synchronized then here is what could happen:
Thread A enters the getter, tests myVar and finds that it equals NULL.
Thread B enters the setter, sets myVar non-null, calls myVarLock.notifyAll(), returns. The notification is lost because no other thread was waiting for it.
Thread A calls myVarLock.wait() and waits forever, for an event that is never going to happen again.
I'm doing this little exercise myself trying to understand how should I work with concurrency and threads.
It happens that sometimes I have an object that I can't modify its source code and that is not thread-safe, so I want it to be accessed just by one thread.
In this example that thirdparty object that I can't touch is called Holdeable. What I do is trying to wrap it into a class called Holder that has synchronized methods, and I expect that by doing it only one thread can access that Holdeable object. At sometime I null the reference to the Holdeable object and I want it properly done so when the other thread evaluates mHolder.getHoldeable()==null is true, and avoids entering the code that can cause a NullPointerException.
My last attempt included a synchronized block, which is this:
class Holder {
Holdeable mHoldeable;
public synchronized void setHoldeable(Holdeable holdeable) { mHoldeable = holdeable; }
public synchronized Holdeable getHoldeable() { return mHoldeable; }
}
class Holdeable { // Cannot be modified, that would be to cheat :D
public int someValue;
}
public class MainClass {
private static Holder mHolder;
public static void main(String[] args) {
try {
Holdeable holdeable = new Holdeable();
mHolder = new Holder();
mHolder.setHoldeable(holdeable);
new Thread(new Runnable() {
#Override
public void run() {
try {
while(true) {
synchronized(mHolder) {
if(mHolder.getHoldeable() != null) {
Thread.sleep(23);
System.out.println(mHolder.getHoldeable().someValue);
} else {
System.out.println("No holder!");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000);
mHolder.getHoldeable().someValue = 2;
Thread.sleep(1500);
mHolder.getHoldeable().someValue = 3;
Thread.sleep(500);
mHolder.setHoldeable(null);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This example avoids throwing a NullPointerException, but as you can see, it just takes a lot to execute with so much locking. I'm struggling with this while I read the book "The art of concurrency" to see if I finally get it.
What do you think?
Your code is not thread-safe. You have two levels of locking:
Holder's methods are synchronized;
you synchronize on the Holder instance.
Point 1. doesn't give you enough synchronization because it covers only fetching holdeable and not accessing its properties;
Point 2. doesn't give you any synchronization at all because you are acquiring the lock only in one thread.
I suggest you use only point 2. and apply it consistently.
BTW your program takes so long to execute because it calls Thread.sleep. The performance of locking is way too high for you to be able to notice it without involving tight loops repeating at least hundreds of thousands of times.
public class Holder {
final Holdeable mHoldeable;
Holder(Holdeable holdeable) {
this.mHoldeable = Objects.requireNonNull(holdeable, "Holdeable cannot be null");
}
Holdeable get() {
return mHoldeable;
}
}
Using this construct will make your life so much easier. And as you might have noticed: it as well removes the need to synchronize. And if I ever write a book, that would be in it on page one. ;)
Threading and synchronization is done almost 100% on architectural level, adding some synchronized blocks is just a backup/quick & dirty solution.
I want to test if lazy initialization is thread-safe, so my code is below:
package LazyInit;
import java.util.Random;
public class UnThreadSafeLazyInit {
private ExpensiveObject instance = null;
public ExpensiveObject getInstance() {
if (null == instance) {
instance = new ExpensiveObject();
}
System.out.println("instance=" + instance);
return instance;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
UnThreadSafeLazyInit init = new UnThreadSafeLazyInit();
Task t1 = init.new Task();
Task t2 = init.new Task();
t1.start();
t2.start();
try {
Thread.sleep(4000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(t1.getInstance() == t2.getInstance());
}
}
static class ExpensiveObject {
}
class Task extends Thread {
private ExpensiveObject instance = null;
private Random rand = new Random(47);
public void setInstance () {
this.instance = UnThreadSafeLazyInit.this.getInstance();
}
public ExpensiveObject getInstance() {
return instance;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(rand.nextInt(1000));
} catch (Exception e) {
e.printStackTrace();
}
setInstance();
}
}
}
In my code, every time I new two Thead task to call public ExpensiveObject getInstance(), in order to prove the two instance maybe not the same reference to ExpensiveObject since race Condition.
When I ran it, it always return true by t1.getInstance() == t1.getInstance().
As I know, if I don't synchronized the function public ExpensiveObject getInstance(), it could be return false since race Condition exists in Lazy Initialization.
I need to find out which code is error.
Thank you.
It is not thread safe, just by inspection of the code. The problem you have is that delays of many milli-seconds is an enormous time to a computer and you are very, very unlikely to see a problem with this type of testing.
For example, the typical delay between updating a volatile field and it being visible to other threads is around 5 nano-seconds. It is for about this long that your solution is not thread safe. You are waiting up up to 1,000,000,000 nano-seconds to see if you get an issue.
This is like trying to see if fireworks lasting 5 seconds went off, but closing your eyes 317 years before concluding there was no fireworks.
Why it is not thread safe has already been covered by others. But I wanted to comment on your title: "I want to test if lazy initialization is thread-safe".
You can't test that a piece of code is thread safe. You might be able to find a test that proves that it is not, but testing only can't prove thread safety:
your test might not interleave threads in a way that reproduces the problem
your test might introduce additional synchronization (for example System.out.println is synchronized) that hides the actual issues
the issue might only appear in a very rare scenario that a few test runs will probably not encounter
the issue might only appear on certain JVMs / CPUs and the fact that your tests "works" with one specific setup does anyway not prove anything
The easiest way would be to make ExpensiveObject a really expensive object:
public class ExpensiveObject {
public ExpensiveObject() {
System.out.println("I'm expensive!");
try {
Thread.sleep(2000L);
}
catch (InterruptedException e) {
}
System.out.println("See. It took 2 seconds to create me!");
}
}
Otherwise, the chance of entering into a rece condition is very small, especially since one thread is started after the other one, and thus calls setInstance() after the other one.
It's not Thread-safe. You're just lucky this time. Modify your code:
public ExpensiveObject getInstance() {
if (null == instance) {
System.out.println("old instance=" + instance);
instance = new ExpensiveObject();
System.out.println("new instance=" + instance);
}
return instance;
}
// In main
Thread.sleep(40); // Thread.sleep(4000);
// In run
Thread.sleep(rand.nextInt(10)); // Thread.sleep(rand.nextInt(1000));
I see a lot of false in my console with this code.
I need to lock two objects in a functionality and the current code looke like this;
Object obj1 = ...//get from somewhere
Object obj2 = ...//get from somewhere
synchronized(obj1){
...//blah
synchronized(obj2){
...//blah
}
}
As you can see this is a plain and straight recipe for deadlocks if another thread runs this piece of code with obj1 and two reversed.
Is there a way to avoid this situation using concurrency-utils locks?
I was contemplating maintaining a map of objects and their locks and verifying if they were available to take, but can't seem to come up with a clean way which will predict the lock order.
Although you preserve locking order, if obj1 is switched with obj2 you'll run into deadlock.
You must look for another solution to avoid this cases: lock ordering + optional tie breaking lock
int fromHash = System.identityHashCode(obj1);
int toHash = System.identityHashCode(obj2);
if (fromHash < toHash) {
synchronized (obj1) {
synchronized (obj2) {
........
}
}
} else if (fromHash > toHash) {
synchronized (obj2) {
synchronized (obj1) {
........
}
}
} else {
synchronized (TIE_LOCK) {
synchronized (fromAcct) {
synchronized (toAcct) {
...
}
}
}
Depending on what you are doing you may be able to take what you want from the first locked object and use that information to process the second locked object. e.g.
instead of
synchronized(list1) {
for(String s : list1) {
synchronized(list2) {
// do something with both lists.
}
}
}
do this
List<String> listCopy;
synchronized(list1) {
listCopy = new ArrayList<String>(list1);
}
synchornized(list2) {
// do something with liastCopy and list2
}
You can see you only have lock at a time so you won't get a deadlock.
You need to consistently lock in the order of obj1 and then obj2. If you never violate this order, you won't have deadlocks.
Essentially what you have is the dining philospher's problem.
https://en.wikipedia.org/wiki/Dining_philosophers_problem
Ovidiu Lupas's answer is similar to Dijkstra's Resource Heirarchy solution, but there are 3 more solutions, explained on the wiki page
This is what the arbitrator solution looks like. If all of the objects which you're operating from inherit from the same type, you could use static class variables to implement the arbitrators on the class of objects.
import java.util.concurrent.locks.Lock;
public void init()
{
Lock arbitrator = new Lock();
}
public void meth1()
{
arbitrator.lock();
synchronized (obj1) {
synchronized (obj2) {
arbitrator.unlock();
// Do Stuff
}
}
}
public void meth2()
{
arbitrator.lock();
synchronized (obj2) {
synchronized (obj1) {
arbitrator.unlock();
// Do Stuff
}
}
}
The Chandy/Misra solution requires a lot of message passing so I'm not going to implement it, but wikipedia has a pretty good explaination
You can solve it in other way I suppose.
class Obj implements Comparable<Obj> {
// basically your original class + compare(Obj other) implementation
}
class ObjLock implements Lock, Comparable<ObjLock> {
private final Lock lock;
private final Obj obj; // your original object
ObjLock(Obj obj) {
this.obj = obj;
this.lock = new ReentrantLock();
}
#Override
public int compare(ObjLock other) {
return this.obj.compare(other.obj); // ObjLock comparison based on Obj comparison
}
// + reimplement Lock methods with this.lock invocations
}
Then do
class ObjLocksGroup {
private final List<ObjLock> objLocks;
ObjLocksGroup(ObjLock... objLocks) {
this.objLocks = stream(objLocks)
.sorted() // due to ObjLock implements Comparable and sorting you are sure that order of ObjLock... will always be the same
.collect(toList));
}
void lock() {
this.objLocks.forEach(ObjLock::lock);
}
void unlock() {
this.objLocks.forEach(ObjLock::unlock);
}
}
And use it as you want:
ObjLocksGroup locks = new ObjLocksGroup(obj1, obj2) // the same as obj2, obj1, order does not matter anymore.
locks.lock();
locks.unlock();