我是同步主题的新手,在尝试访问同步对象时,无法在任何地方找到有关使用wait()
,notify()
和notifyAll()
方法的明确信息。例如,如果我们有这样的代码:
class X extends Thread {
int x;
public void methodX()
{
synchronized(this)
{
//some operations on x
}
}
}
class Y extends Thread {
public void methodY(X x)
{
int z = x.x;
}
}
我们应该在wait()
和methodY()
notify()
结束时致电methodX()
吗?
否则我们不会将任何值分配给z
,否则线程会在没有明确调用wait()
的情况下等待,直到X解锁?
答案 0 :(得分:2)
因此,您需要methodY
等待methodX
执行,一种有效的方法是wait
和notify
或notifyAll
。当然还有其他多种方式,但其中一种方式是有效的。鉴于您甚至可能不需要同步块。
void methodX(){
// do your work here
this.notifyAll();
}
void methodY(X x){
x.wait();
int x = X.x;
}
您可以考虑将阻止代码放在getX
中的X
方法中,但上述内容将起作用(这是一个BIG IF),您可以保证methodY
在methodX
之前启动{ {1}}因为否则methodY
会错过notify
来电。
以上所有内容都表示,我同意JB Nizet
,您可能会考虑使用更高级别的机制,例如Semaphore / Mutex /等。这些可以减轻复杂性。例如,如果您使用CountDownLatch
并使用计数1创建它,您的代码可能会更强大...
考虑:
class X{
volatile int x;
final CountDownLatch cdl = new CountDownLatch(1);
void methodX(){
// do work here
cdl.countDown();
}
int getX(){
cdl.await();
return x;
}
}
class Y{
void methodY(X x){
int z = X.getX();
}
}
以上每次都会有效,没有任何订购风险。