我上了这个课:
public class MyThread implements Runnable {
private static boolean canAccess = true;
private Thread t;
public FirstThread(String name) {
t = new Thread(this);
t.setName(name);
}
public void start() {
t.start();
}
private synchronized void accessed(String name) throws InterruptedException {
if (canAccess) {
canAccess = false;
System.out.println("Accessed " + name);
try {
Thread.sleep(5000);
} catch (Exception e) {
}
canAccess = true;
System.out.println("NOTIFY: " + name);
notifyAll();
}
System.out.println("WAIT: " + name);
wait();
}
@Override
public void run() {
while (true) {
try {
accessed(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这是我的输出:
Accessed 1
WAIT: 3
WAIT: 5
WAIT: 7
WAIT: 9
WAIT: 0
WAIT: 2
WAIT: 4
WAIT: 6
WAIT: 8
NOTIFY: 1
WAIT: 1
并且我的应用程序冻结(死锁状态)。
似乎notifyAll方法不起作用。我的错误在哪里?
我的主类。
public class Main {
public static void main(String[] args) {
MyThread [] threads = new MyThread[10];
for(int i=0;i<threads.length;i++) {
threads[i] = new MyThread(""+i);
threads[i].start();
}
}
}
最佳答案
wait
意味着线程释放锁定并进入 hibernate 状态,直到另一个线程通知它为止。 notifyAll
意味着该线程告诉所有其他线程,这些线程正在等待当前同步块(synchronized block)中正在使用的锁,以唤醒并尝试再次获取该锁。您的代码示例没有任何情况,多个线程试图获取同一锁,因此在这里使用wait和notifyAll没有任何意义。一旦调用wait,就没有什么可以唤醒线程的。
等待和通知的一种典型用法:您可能有许多生产者将 Material 放入队列中,而使用方线程将 Material 从队列中取出。队列具有使用者调用的take方法,如果队列为空,则它调用wait并被使用者阻塞。队列有一个put方法,当有什么东西进入队列时,该方法将调用notifyAll,以便唤醒所有等待的使用者线程。
Java教程中有a producer-consumer example of using wait and notifyAll。