[英]java and synchronization
I am preparing for the SCJP exam and I am having trouble with fully understanding synchronization. 我正在为SCJP考试做准备,但是在完全了解同步方面遇到了麻烦。 At line 6, I have read that the thread running in main needs a lock on 'b'.
在第6行,我读到main中运行的线程需要锁定'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.
继续前进,main中的线程释放此锁定,并等待'b中的线程完成其run方法。 The thread in 'b' is then meant to notify the thread in main that it has completed.
然后,“ b”中的线程将通知main中的线程已完成。 However, it does not look like it is notifying any specific thread here.
但是,它看起来并不像在这里通知任何特定线程。 This example is from the Sierra and Bates SCJP book.
此示例来自Sierra and Bates SCJP书。 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
. 这两个线程在同一个
Object
上同步,即b
。 main()
first aquires the lock, but then calls b.wait()
, which releases the lock and waits for someone to call notify()
on b
. main()
首先获取锁,然后调用b.wait()
,后者释放锁并等待有人在b
上调用notify()
。
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. 这意味着当在本例中在
b
调用的run()
方法调用notify()
,这将再次唤醒main()
方法。
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. 因此,在
b
上获得锁并不真正重要,重要的是两个线程都获得相同的锁,否则wait()/notify()
合作将无法正常进行。
At line 6, I have read that the thread running in main needs a lock on 'b'.
在第6行,我读到main中运行的线程需要锁定'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.
作为开发人员,您可能会得出结论,有一个特定的线程将被通知,这也许是因为它是唯一的线程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
. 发生的是
main
线程在ThreadB
对象上同步并wait
。
When ThreadB
finishes a notify
is raised and as a result main
is woken up and continues. 当
ThreadB
完成时,将引发一个notify
,结果main
被唤醒并继续。
But this is not code you would normally write ie use Thread
objects for synchronization
. 但这不是您通常会编写的代码,即使用
Thread
对象进行synchronization
。
To see how corner case this is, just remove the notify
from the loop of ThreadB
. 要查看情况如何,只需从
ThreadB
循环中删除notify
。
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. 由于您在
Thread
对象上进行了同步,因此该代码仍然可以使用,并且在Thread
完成后,该实现会引发一个通知。
The behavior is counter-intuitive and error-prone. 该行为是违反直觉的并且容易出错。
The code make use of wait()
mechanism to ensure that result
is computed by other ThreadB
. 该代码利用
wait()
机制来确保result
由其他ThreadB
计算。
To wait on object you need to acquire lock on that object that is where line 6
, synchronized (b)
comes in to picture. 要等待对象,您需要获取该对象的锁定,该对象位于
line 6
,其中已synchronized (b)
进入图片。
Better way to execute same program is using Thread#join() method. 执行相同程序的更好方法是使用Thread#join()方法。
public final void join()
throws InterruptedException
Waits for this thread to die.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.