简体   繁体   中英

java and synchronization

I am preparing for the SCJP exam and I am having trouble with fully understanding synchronization. At line 6, I have read that the thread running in main needs a lock on 'b'. Why does it need a lock on this object? My understanding is that a synchronized block of code is a protected area that only one thread can be in at any time? Moving on,the thread in main releases this lock and waits for the the thread in 'b to complete its run method. The thread in 'b' is then meant to notify the thread in main that it has completed. However, it does not look like it is notifying any specific thread here. This example is from the Sierra and Bates SCJP book. Any light that can be shed on this would be grately 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();  
        }  
    }  
}

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

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

So, that the lock is aquired on b isn't really important here, the important part is that both threads aquire the same lock, or the wait()/notify() cooperation won't work.

At line 6, I have read that the thread running in main needs a lock on 'b'. Why does it need a lock on this object?

Because that is what that line does. It acquires that resource. Other thread can get other synchronized block, but no other thread can acquire a lock on that object.

it does not look like it is notifying any specific thread here.

This is true. The program has no idea which thread will be notify or even if any thread will be notified. You as the developer may conclude there is a particular thread which will be notified, perhaps because its the only thread wait()ing.

This is a very corner case and you would not do that.
What happens is that main thread synchronizes on ThreadB object and wait .
When ThreadB finishes a notify is raised and as a result main is woken up and continues.
But this is not code you would normally write ie use Thread objects for synchronization .
To see how corner case this is, just remove the notify from the loop of ThreadB .
The code will still work due to the fact you synchronize on a Thread object and the implementation raises a notify after a Thread has finished.
The behavior is counter-intuitive and error-prone.

The code make use of wait() mechanism to ensure that result is computed by other ThreadB .

To wait on object you need to acquire lock on that object that is where line 6 , synchronized (b) comes in to picture.

Better way to execute same program is using Thread#join() method.

public final void join()
            throws InterruptedException

Waits for this thread to die.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM