use*_*336 1 java multithreading synchronization deadlock notify
在我的java代码中,threadB创建了nb*threadA并等待,直到myobj的值等于nb. myobj最初等于0,每个threadA递增它,当它等于nb时,最后一个threadA通知ThreadB.
运行程序时,不会通知threadB并且不会继续运行.谁能告诉我这段代码中的问题在哪里?
public class Myclass {
static Long myobj = new Long(0);
static int nb = 1;
public static void main(String[] args) {
ThreadA[] threadA = new ThreadA[nb];
ThreadB threadB = new ThreadB(threadA);
}
}
public class ThreadA extends Thread {
public ThreadA() {
this.start();
}
public void run() {
// do lot of computation
Myclass.myobj = Myclass.myobj + 1;
if (Myclass.myobj.intValue() == Myclass.myobj.nb) {
synchronized (Myclass.myobj) {
Myclass.myobj.notify();
}
}
}
}
public class ThreadB extends Thread {
ThreadA[] threadA;
public ThreadB(ThreadA[] threadA) {
this.threadA = threadA;
this.start();
}
public void run() {
for (int i = 0; i < threadA.length; i++) {
threadA[i] = new ThreadA();
}
synchronized (Myclass.myobj) {
while (Myclass.myobj.intValue() != Myclass.myobj.nb) {
Myclass.myobj.wait();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我对所有可能出错但却没有引起问题的事情感到困惑.
真正的问题是
if (Myclass.myobj.intValue() == Myclass.myobj.nb)
Run Code Online (Sandbox Code Playgroud)
每次被称为myobj< 时,永远不会是真的nb
我该怎么写这段代码?
int nb = ....
ExecutorService es = Executors.newFixedThreadPool(nb)
for (int i = 0; i < nb; i++)
es.submit(new Runnable() {
@Override
public void run() {
// do lot of computation
}
});
es.shutdown();
es.awaitTermination(1, TimeUnit.HOURS);
Run Code Online (Sandbox Code Playgroud)
这里有很多东西需要改进,我觉得有必要列出它们
Long当你的意思是使用时不要使用long.在这个原因你似乎想要使用int.new Long(0)因为你可以使用更高效的自动装箱.如果这样做,请不要将其用作锁定对象.static在线程之间使用可变字段.Thread.创建一个传递给线程的Runnable.但是,您的基本问题是您正在等待与您通知的对象不同的对象.
synchronized(Myclass.myobj){ // lock the object you might be waiting on.
Myclass.myobj=Myclass.myobj+1; // change this to another object.
Myclass.myobj.notify(); // notify a different object.
}
Run Code Online (Sandbox Code Playgroud)