Java and synchronization

I am preparing for the SCJP exam and I am having trouble fully understanding synchronization. On line 6, I read that a thread that runs mostly requires a lock on 'b'. Why do we need a lock for this object? I understand that a synchronized block of code is a protected area in which there can be only one thread at a time? Moving on, the thread basically releases this lock and waits for the thread in 'b to complete its start method. Then the thread in 'b' should notify the main thread that it completed. However, it does not appear that he is notifying any particular topic of this. This example is from the Sierra and Bates SCJP book. Any light that could be shed on this would be greatly appreciated. thanks

class ThreadA { public static void main(String [] args) { ThreadB b = new ThreadB(); b.start(); **synchronized(b) { //line 6** try { System.out.println("Waiting for b to complete..."); b.wait(); } catch (InterruptedException e) {} System.out.println("Total is: " + b.total); } } } } class ThreadB extends Thread { int total; public void run() { System.out.println("K"); synchronized(this) { for(int i=0;i<100;i++) { total += i; } notify(); } } } 
+4
source share
4 answers

On line 6, I read that for a thread that runs mostly, it needs a lock on 'b'. Why do we need a lock for this object?

Because this is what this line does. He is acquiring this resource. Another thread can get another synchronized block, but no other thread can get a lock on this object.

it does not look like it is notifying any particular thread about this.

It's right. The program does not know which thread will be notified or even if any thread is notified. You, as a developer, can conclude that there is a specific thread that will be notified, perhaps because its only thread is wait () ing.

+2
source

Both threads are synchronized on the same Object here, namely b . main() first uses the lock, but then calls b.wait() , which releases the lock and waits for someone to call notify() on b .

This means that when the run() method, which in this case is called on b , calls notify() , this will again awaken the main() method.

Thus, locking on b is not very important here, the important part is that both threads have the same lock, or the wait()/notify() collaboration will not work.

+2
source

This is a very angular case, and you would not do it.
It happens that the main thread synchronizes with the ThreadB and wait objects.
When ThreadB ends a notify , and as a result, main wakes up and continues.
But this is not the code you usually write, i.e. Use Thread objects for synchronization .
To find out how to do this, simply remove notify from the ThreadB loop.
The code will still work because you are synchronizing the Thread object, and the implementation will trigger a notification after the Thread completes.
Behavior is intuitive and error prone.

+2
source

The code uses the wait() mechanism to ensure that the result evaluated by another ThreadB .

To wait on an object, you need to get a lock on the object where line 6 is located, synchronized (b) .

The best way to execute the same program is with the Thread # join () method .

 public final void join() throws InterruptedException Waits for this thread to die. 
0
source

Source: https://habr.com/ru/post/1435661/


All Articles