synchronization mechanism in Java - java

I need to make sure I understand synchronization mechanism in java, here are couple scenarios Id like to ask about:
theres a list 'a':
List a
and there are two functions:
void foo(int i){
synchronized(a){
a.add(i);
}
}
int goo(){
return a.size();
}
If there are multiple threads running, and one of them uses synchronized code block in foo, can other threads at this time access goo (or more specifically, access 'a'?)? How about the opposite, if there is a thread accessing a at the momen through goo (which is unsynchronized), can a thread enter the synchronized block of foo? or is it going to wait on it?
Let there be:
void synchronized foo(){
// do stuff
notifyAll();
//do stuff
if(someStatement)
return;
wait();
//do stuff
}
Some thread enters foo and reaches wait block, it releases the key of 'this', right? Second thread enters foo, and reaches notifyAll, at this point the first thread who was waiting should wake up and continue the code of foo, but it doesnt make sense because the other thread is currently holding the key. So what will happen?
Let there be:
class A implements Runnable {
Thread b;
foo(){
b= new Thread(()-> { /*some lambda function*/};
b.start();
}
goo(){
//here I'd like to notify the thread of b, how do I do it?
}
}
What should I do if I want to notify a thread that I created with lambda function? this means I dont have a reference to it, but I do have a reference to object 'b'.
Thanks in advance.
This is me trying to learn java synchronization

If there are multiple threads running, and one of them uses synchronized code block in foo, can other threads at this time access goo (or more specifically, access 'a'?)? How about the opposite, if there is a thread accessing a at the momen through goo (which is unsynchronized), can a thread enter the synchronized block of foo? or is it going to wait on it?
Yes, multiple threads can access those methods at the same time currently, either way round.
However, this is not correct code: you need to synchronize access to a.size() on a in order to ensure that you see any updates to the data structure that occurred in goo. For example, foo might see a size of 0 even after you have added something into the list using foo.
So, you need to make the code such that two threads can't be in those blocks at the same time.

Related

Purpose of different monitor objects in synchronized

Could someone explain the difference between synchronized(this) and synchronized (c)?
I refereed various answers(1,2,3,4,5) but not able to understand and getting confused.
public class Check {
Consumer c = new Consumer(null);
public void getSynch() {
synchronized (this) {
// doing some task
System.out.println("Start");
}
synchronized (c) {
// doing some task
System.out.println("End");
}
}
}
I am able to understand the synchronized concept but not monitor object. Please explain in a simple way.
synchronized always works on a monitor object (sometimes also called lock or semaphore). Think of it as a token: when a thread enters a synchronized block it grads the token and other threads need to wait for the token to be returned. If you have multiple different monitor objects you basically have different tokens and thus synchronized blocks that operate on different monitors can run in parallel.
There are many possibilities with this and many possible use cases. One could be that multiple instances of a class could run in parallel but need access to a shared and non-threadsafe resource. You then could use that resource or any other object that represents the "token" for that resource as the monitor object.
However, note that there's potential for deadlocks, e.g. in the following situation:
Block 1:
synchronized(A) {
//do something with A
synchronized(B) {
//do something with B
}
}
Block 2:
synchronized(B) {
//do something with B
synchronized(A) {
//do something with A
}
}
Here both outer synchronized blocks could be entered in parallel because the two monitors A and B are available but then need to grab the other monitor and because they are now locked both threads would have to wait - class deadlock.
Also have a look at the dining philosophers problem which handles that topic as well (here the forks could be considered the monitor objects).
Edit:
In your case (the code you've posted), multiple threads could try to call getSynch() on the same instance of Check. The first block synchronizes on the instance itself thus preventing multiple threads from entering that block if called on the same instance.
The second block synchronizes on c which is a different object and could change over time. Assume the first block (synchronized(this) { ... }) changes c to reference another instance of Consumer. In that case you could have multiple threads run that block in parallel, e.g. if one entered the synchronized(c) block before the other thread reassigns c.

java threading lock variable properly

Thread A does:
class A{
public String value;
public void methodA(String value){ //lets say value="test"
this.value=value;
//some code
// Thread B interrupts
System.out.println(value); // prints "haha" but I want it to be "test"
}
}
Thread B does:
class B{
public void methodB(){
a.setValue("haha");
}
}
methodB and methodA are some kinds of listener methods, which are executed in separate Threads.
How can I make sure that value does not change, as long as methodA has not finished? But I want also that "haha" is assigned to value afterwards. So I want B to wait till A has finished methodA and then assign "haha" to value.
The easiest way is to use 'synchronized' keyword on method that change the value of a field.
For example we have class that stores the data:
public class Data {
String value = "";
public synchronized void setValue(String val) {
this.value = val;
System.out.println(val);
}
}
And then Threads only use this method to update the value. Only one thread at the time can execute this method (no interrupts).
If you want to propagate this on two methods (like I suppose is the case). You can use two options. Or use synchronized on both methods or use external lock object.
If you want to be sure, that for example thread A has to be first to execute, you can use CountDownLatch object, which will stop other threads until thread A won't decrement the latch.
There are many ways to handle synchronization. You should be more precise to what you want to achieve and what kind of scenario you want to handle. Like for example - Is a.setValue("haha") a method from class A?
I would also recommend to look at documentation about concurrency https://docs.oracle.com/javase/tutorial/essential/concurrency/ .
If you just want methodA() to complete before methodB() is called, then you should call both methods from the same thread. In general, if you want your program to do certain things in a certain order, the best way to accomplish it is
to do all of the things in a single thread.
On the other hand, you might want both threads to work in parallel most of the time, but there might be one particular point that you don't want thread B to pass until thread A gets there. The Java standard library provides a variety of different synchronization objects that you could use. E.g., java.util.concurrent.CountDownLatch.
Initialization:
CountDownLatch countDownLatch=new CountDownLatch(1);
threadA.start();
threadB.start();
Thread A:
doSomeStuff();
methodA();
countDownLatch.countDown();
doSomeMoreStuff();
ThreadB:
doSomeOtherStuff();
countDownLatch.await();
methodB();
doSomeMoreOtherStuff();
The doSomeStuff() and doSomeOtherStuff() calls could happen concurrently, and the doSomeMoreStuff() and doSomeMoreOtherStuff() calls could happen concurrently, but the methodA() and methodB() would be serialized in this case.

Java multithreading - locking without waiting

I have a java multithreading issue. I have 2 threads accessing a methodA() which has a for loop inside and in the loop calls a methodB(). The method A should be locked using a thread-name lock and the method B should be locked on the object id that the method B operates on. Check the below code.
Currrent code
private static final ConcurrentHashMap<Object, Object> LOCKS = new ConcurrentHashMap<Object, Object>();
private void methodA(){
LOCKS.putIfAbsent(Thread.currentThread().getName(), new Object()))
synchronized (LOCKS.putIfAbsent(Thread.currentThread().getName(), new Object())) {
for(loop through all objects) {
methodB(Object1);
}
}
}
private void methodB(Object1 object1) {
LOCKS.putIfAbsent(object1.getObjectId(), new Object()))
synchronized(LOCKS.putIfAbsent(object1.getObjectId(), new Object())){
//<Work on object1>
}
}
I had done the above code to ensure that 2 different threads should be able to paralleley access methodA(), but should not work on same Object1 at a time in methodB() (which is invoked by methodA()).
ie; Though I want Thread A and Thread B to access methodA() at the same time, which in turn will loop through all objects in 'for' loop and will operate on each by calling methodB(), I dont want thread A and B to act on the SAME object instance at a time. Hence the above code to lock methodB() based on object instance ID.
The improvement needed.
In the above code if Thread A and Thread B comes to methodB() and finds that they both want to work over the same object 'obj1', right now with the above code either Thread A will wait or Thread B will wait for the other one to finish depending on who reached and locked methodB() first.
But imagine a case, where Thread A getting the lock first and executing methodB() takes 9 hours to finish processing 'obj1'. Thread B in this case will need to wait for the entire 9 hours before getting a chance to execute methodB() and thereby processing 'obj1'.
I don't want this to happen. Thread B, once it finds that methodB() is locked in the name of 'obj1' by Thread A should move on (and come back to obj1 later) to try locking and processing other objects. ie; it should try processing other objects in the 'for' loop like obj1, obj2 etc in the list of objects.
Any inputs to solve this 'lock without wait' problem will be appreciated.
Many thanks in advance for any help.
Some clarifications to improve the answers.
Both methodA() and methodB() is in same class. The methodB() is not in the Object class.
Actually Thread A and Thread B are timer threads that calls many methods including A and B. Hence the thread level lock (because thread gets called every 15 mins or so and there is a chance that the first execution of methodA() wont be completed before a second call to it).
methodB(Obj1) always takes a Object1 param and must be locked on it. The reason is, in this class there are be other methods say methodC(Obj1) and methodD(Obj1) that also takes in an Object1 param. These methods should not get executed at the same time for same instance of Object1. Hence the lock on Object1 param needed.
The Thread B finding that methodB(Obj1 obj) is already locked by Thread A() on obj1 needs to somehow call methodB() again but with a different object, say obj2. It should come back to obj1 once it finishes with the others.
The best thing you can do is to keep things simple.
The method A should be locked using a thread-name lock
Only locking shared objects makes sense. Lock a thread local lock is pointless.
synchronized(LOCKS.putIfAbsent(object1.getObjectId(), new Object()))
That will return null and throw a NullPointerException the first time it is run.
I would replace the code with
private void methodA(){
List<Object1> objects = new ArrayList<>(this.objectList);
while(true) {
for(Iterator<Object1> iter = objects.iterator() : objects)
if(object1.methodB())
iter.remove();
if(objects.isEmpty()) break;
Thread.sleep(WAIT_TIME_BEFORE_TRYING_AGAIN);
}
}
// in class for Object1
final Lock lock = new ReentrantLock();
public boolean methodB() {
if (!lock.tryLock())
return false;
try {
// work on this
return true;
} finally {
lock.unlock();
}
}
Depending on how you want to handle object which cannot be locked, you could add them to a background ExecutorService. You could have methodA repeatedly call all the remaining objects for which this fails.
Ideally you would find a way to minimise the time locked or even remove the need for a lock entirely. e.g. Classes like AtomicReference and CopyOnWriteArrayList are thread safe and lockless.
I am not a Java guy, but in my opinion you will not achieve this with synchronized. I believe you will need to do your own locking.
If you create a java.util.concurrent.locks.ReentrantLock you can use tryLock to enter the lock if it is not yet locked. methodA needs to know which methodB call was successful or which was canceled because the lock was not possible. So you could do the lock handling in methodA, giving you full control there. Or you could do the locking in methodB, but then you need some return value or exception handling to signal back to methodA if methodB did its work or if it did not get the lock.
Of course you will also need to keep a list in methodA of the objects you already went through or of the objects you still need to work on.
Does it matter if one thread pass occasionally 'misses' an object on a pass-through? If not:
Store all the objects in a lockable queue-style container. Have threads A, B etc. pop one out, call methods on it and then push it back in. It is then not possible for the threads to operate on the same object at the same time. The only lock is then on the container push/pop and no thread needs to block for any extended time.
..or something like that. I always try to avoid complex locking schemes - they always seem to screw up :(
I suggest a different approach. Instead of directly invoking the method, put a command object in a queue and have a thread (or an executor) process the commands.
When a command appears in the queue, try to get the lock. If that doesn't work, add the command to the end of the queue. This will make sure the command is tried again eventually.
Drawback: A command could be postponed indefinitely if some thread happens to have lock on it every time it's tried for execution.
The solution here would be to make sure you only lock what you need. That way, when you see "oh, this is locked", you know that someone is already working on the task and you can simply forget about the command (-> don't do work twice).

Differences between synchronized(this) and synchronized(objectReference)

I'd like to better understand the mechanics of what actually happens when thread enters the synchronized(this) block vs synchronized(someObjectReference) block.
synchronized (this) {
// Statement 1
// Statement 2
}
synchronized (someObjectReference) {
// Statement 1
// Statement 2
}
As i understand it: (am i missing something? am i wrong?)
In both cases, only 1 thread can access synchronized block at a time
When we're synchronizing on someObjectReference :
Only 1 thread at a time may access/modify it in this block
Only 1 thread at a time may enter this block
What other mechanics are there please?
synchronized (objectReference) {
// Statement 1 dealing with someObjectReference
// Statement 2 not dealing with someObjectReference
}
In the example above, does it make any sense adding statements not dealing with mutex into the synchronized block?
There's only a difference when you mix the two together.
The single, basic rule of synchronized(foo) is that only one thread can be in a synchronized(foo) block for the same foo at any given time. That's it. (The only caveat maybe worth mentioning is that a thread can be inside several nested synchronized(foo) blocks for the same foo.)
If some code is inside a synchronized(foo) block, and some code is inside a synchronized(bar) block, then those pieces of code can run simultaneously -- but you can't have two threads running code in synchronized(foo) blocks simultaneously.
In both cases, only 1 thread can access synchronized block at a time
Not really. For exemple, when synchronizing on "this", 2 threads can access to the same block if they have 2 different instances of the same class. But yes, for one instance, there will be only one access to the block. And there will also have only one acess to any synchronized block on this
"Synchronized" means that only 1 thread can have access to any synchronized block on the same instance. So if you have 2 synchronized block in 2 different source files, but on the same instance, if one thread is inside one of those blocks, another thread cannot access to both synchronized block
About "what to do within a synchronized block" : do only things dealing with the synchronized object. Any other instruction that doesn't need synchronization will lock the ressource for nothing, an potentially create a bottleneck
Synchronize basically means program request to take a lock on the specified object...If a Thread is not able to enter any synchronized block then that means any other thread has already taken lock on the specified object..BLock of code specify that inside this region a thread can enter if lock is successfully acquired..
In both cases, only 1 thread can access synchronized block at a time
--Depend on the object to be locked availability
One important thing to note about synchronizing on this deals with visibility. Lets say you have a class A and it synchronizes on this. Any code that uses A has a reference to the object A is using to lock on. This means it is possible for a user of A to create a deadlock if they also lock on the A instance.
public class A implements Runnable {
public void run() {
synchronized (this) {
// something that blocks waiting for a signal
}
//other code
}
}
public class DeadLock {
public void deadLock() {
A a = new A();
Thread t = new Thread(a);
t.start();
Thread.sleep(5000); //make sure other thread starts and enters synchronized block
synchronized (a) {
// THIS CODE BLOCK NEVER EXECUTES
// signal a
}
}
}
Where as, if you always synchronize on a private member variable, you know that you are the only one using that reference as a lock.

Do I need to synchronize methods inside the run method in java when calling start method?

Can anyone tell me if I'm right or not? I have two thread which will run in parallel.
class MyThread extends Thread {
MyThread() {
}
method1() {
}
method2() {
}
method3() {
}
approach(1):
run() {
method1();
method2();
method3();
}
approach(2):
run() {
//the code of method1 is here (no method calling)
//the code of method2 is here (no method calling)
//the code of method3 is here (no method calling)
}
}
class Test{
public static void main(){
Thread t1 = new Thread();
t1.start();
Thread t2 = new Thread();
t2.start();
}
}
method1, method2 and method3 don't access global shared data but their codes perform some write in local variable within the method section, thus I guess I can not allow overlap execution within the method section.
Thereby:
in approach(1): I need to make the methods (method1, method2 and method3) synchronized, right?
in approach(2): No need to synchronize the code sections, right?
If I'm right in both approach, using the approach(2) will give better performance, right?
Short answer: you don't need the synchronization. Both approaches are equivalent from a thread safety perspective.
Longer answer:
It may be worthwhile taking a step back and remembering what the synchronized block does. It does essentially two things:
makes sure that if thread A is inside a block that's synchronized on object M, no other thread can enter a block that's synchronized on the same object M until thread A is done with its block of code
makes sure that if thread A has done work within a block that's synchronized object M, and then finishes that block, and then thread B enters a block that's also synchronized on
M, then thread B will see everything that thread A had done within its synchronized block. This is called establishing the happens-before relationship.
Note that a synchronized method is just shorthand for wrapping the method's code in synchronized (this) { ... }.
In addition to those two things, the Java Memory Model (JMM) guarantees that within one thread, things will happen as if they had not been reordered. (They may actually be reordered for various reasons, including efficiency -- but not in a way that your program can notice within a single thread. For instance, if you do "x = 1; y = 2" the compiler is free to switch that such that y = 2 happens before x = 1, since a single thread can't actually notice the difference. If multiple threads are accessing x and y, then it's very possible, without proper synchronization, for another thread to see y = 2 before it sees x = 1.)
So, getting back to your original question, there are a couple interesting notes.
First, since a synchronized method is shorthand for putting the whole method inside a "synchronized (this) { ... }" block, t1's methods and t2's methods will not be synchronized against the same reference, and thus will not be synchronized relative to each other. t1's methods will only be synchronized against the t1 object, and t2's will only be synchronized against t2. In other words, it would be perfectly fine for t1.method1() and t2.method1() to run at the same time. So, of those two things the synchronized keyword provides, the first one (the exclusivity of entering the block) isn't relevant. Things could go something like:
t1 wants to enter method1. It needs to acquire the t1 monitor, which is not contended -- so it acquires it and enters the block
t2. wants to enter method2. It needs to acquire the 11 monitor, which is not contended -- s it acquires it and enters the block
t1 finishes method1 and releases its hold on the t1 monitor
t2 finishes method1 and releases its hold on the t2 monitor
As for the second thing synchronization does (establishing happens-before), making method1() and method2() synchronized will basically be ensuring that t1.method1() happens-before t1.method2(). But since both of those happen on the same thread anyway (the t1 thread), the JMM anyway guarantees that this will happen.
So it actually gets even a bit uglier. If t1 and t2 did share state -- that is, synchronization would be necessary -- then making the methods synchronized would not be enough. Remember, a synchronized method means synchronized (this) { ... }, so t1's methods would be synchronized against t1, and t2's would be against t2. You actually wouldn't be establishing any happens-before relationship between t1's methods and t2's.
Instead, you'd have to ensure that the methods are synchronized on the same reference. There are various ways to do this, but basically, it has to be a reference to an object that the two threads both know about.
Assume t1 and t2 both know about the same reference, LOCK. Both have methods like:
method1() {
synchronized(LOCK) {
// do whatever
}
}
Now things could go something like this:
t1 wants to enter method1. It needs to acquire the LOCK monitor, which is not contended -- so it acquires it and enters the block
t2 wants to enter method1. It needs to acquire the LOCK monitor, which is already held by t1 -- so t2 is put on hold.
t1 finishes method1 and releases its hold on the LOCK monitor
t2 is now able to acquire the LOCK monitor, so it does, and starts on the meat of method1
t2 finishes method1 and releases its hold on the LOCK monitor
You are saying your methods don't access global shared data and write only local variables so there is no need to synchronize them Because both the threads will be having their own copies of local variables. They will not overlap or something.
This kind of problem is faced in case of static/class variables. If multiple threads try to change the value of static variables at same time then there comes the problem so there we need to synchronize.
If the methods you're calling don't write to global shared data, you don't have to synchronize them.
In a multithreaded program, each thread has its own call stack. The local variables of each method will be separate in each thread, and will not overwrite one another.
Therefore, approach 1 works fine, does not require synchronization overhead, and is much better programming practice because it avoids duplicated code.
Thread-wise your ok. local variables within methods are not shared between threads as each instance running in a thread will have its own stack.
You won't have any speed improvements between the two approaches it is just a better organisation of the code (shorter methods are easier to understand)
If each method is independent of the other you may want to consider if they belong in the same class. If you want the performance gain create 3 different classes and execute multiple threads for each method (performance gains depends on the number of available cores cpu/io ration etc.)
Thereby: in approach(1): I need to make the methods(method1,method2
and method3) synchronized, right? in approach(2): No need to
synchronize the code sections, right?
Invoking in-lined methods v/s invoking multiple methods don't determine whether a method should be synchronized or not. I'd recommend you to read this and then ask for more clarifications.
If I'm right in both approach, using the approach(2) will give better performance, right?
At the cost of breaking down methods into a single god method? Sure, but you would be looking at a "very" miniscule improvement as compared to the lost code readability, something definitely not recommended.
method1, 2 and 3 won't be executed concurrently so if the variables that they read/write are not shared outside the class with other threads while they're running then there is no synchronization required and no need to inline.
If they modify data that other threads will read at the same time that they're running then you need to guard access to that data.
If they read data that other threads will write at the same time that they're running then you need to guard access to that data.
If other threads are expected to read data modified by method1, 2, or 3, then you need to make the run method synchronized (or them in a synchronized block) to set up a gate so that the JVM will set up a memory barrier and ensure that other threads can see the data after m1,2 and 3 are done.

Categories

Resources