Java notifyAll()不工作
在下面的代码中,将调用notifyAll,但不会重新激活其他线程。我得到的输出是 等待通知的测试版时间:1441870698303,activeWriters:1 alpha等待得到通知的时间:1441870698303,activeWriters:1 增量随时通知:1441870698403,ActiveWriter:0 公共类服务生实现可运行{Java notifyAll()不工作,java,multithreading,concurrency,wait,Java,Multithreading,Concurrency,Wait,在下面的代码中,将调用notifyAll,但不会重新激活其他线程。我得到的输出是 等待通知的测试版时间:1441870698303,activeWriters:1 alpha等待得到通知的时间:1441870698303,activeWriters:1 增量随时通知:1441870698403,ActiveWriter:0 公共类服务生实现可运行{ private static int activeWriters; public Waiter(Message msg){
private static int activeWriters;
public Waiter(Message msg){
}
@Override
public void run() {
beforeWrite();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
afterWrite();
}
protected synchronized void beforeWrite(){
while (activeWriters > 0 ) {
try {
System.out.println(Thread.currentThread().getName() +" waiting to get notified at time: "+System.currentTimeMillis()+ ", activeWriters: " + activeWriters);
wait();
System.out.println(Thread.currentThread().getName() +" waiting got notified at time: "+System.currentTimeMillis()+ ", activeWriters: " + activeWriters);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
++activeWriters;
}
protected synchronized void afterWrite(){
--activeWriters;
System.out.println(Thread.currentThread().getName() +" notify all at time: "+System.currentTimeMillis() + ", activeWriters: " + activeWriters);
notifyAll();
}
}
public class WaitNotifyTest {
public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter1 = new Waiter(msg);
Waiter waiter2 = new Waiter(msg);
Waiter waiter3 = new Waiter(msg);
new Thread(waiter1,"alpha").start();
new Thread(waiter2, "beta").start();
new Thread(waiter3, "delta").start();
}
}
调用wait和notify*在指定对象上工作,这意味着notify*会唤醒在同一对象上调用wait的线程
在您的情况下,在3个未连接的不同对象上调用wait和notifyAll,因此这无法工作
您可以添加静态互斥:
private static final Object mutex = new Object();
然后在此对象上调用wait和notify*。请记住首先在互斥锁上进行同步:
synchronized (mutex) {
...
mutex.wait();
...
}
以及:
出于两个原因,对ActiveWriter的所有访问都必须在这些同步块中。当前对ActiveWriter的访问实际上是不同步的,因为您在3个不同的对象上同步。除此之外,ActiveWriter是您的条件变量,您希望通知*其他线程它已更改。为此,请更改变量和notify*调用必须在同一个同步块中。您的程序中存在一个主要的设计缺陷 您正在创建3个单独的服务生类实例,并希望所有实例都以同步方式访问ActiveWriter。这是不可能的,因为实例方法将获取不同的锁,但修改相同的静态变量ActiveWriter 要提供静态变量并发访问,您应该通过.synchronized静态方法访问它们。
一种方法是将beforeWrite和afterWrite方法设置为静态。Thx作为答案。我现在看到3个线程之间确实没有链接。如果我理解正确,我的beforeWrite方法应该更改为protected void beforeWrite{synchronized mutex{而ActiveWriter>0{尝试{mutex.wait;}捕获中断异常e{e.printStackTrace;}}++activeWriters;}}}@user3637488是的,第二种方法也是如此。Thx非常有效。ps很抱歉注释中的代码格式错误:我对并发性做了一些额外的研究。我的代码中ActiveWriter的声明应该是私有静态volatile int activeWriter,因为多个线程访问此变量able?@user3637488如果总是从同步块访问共享变量,则不需要volatile。
synchronized (mutex) {
...
mutex.notifyAll();
...
}