java and synchronization

别等时光非礼了梦想. 提交于 2019-12-07 10:03:55

问题


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();  
        }  
    }  
}

回答1:


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.




回答2:


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.




回答3:


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 i.e. 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.




回答4:


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.


来源:https://stackoverflow.com/questions/12543843/java-and-synchronization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!