我是这堂课:
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();
}
}
}
答案 0 :(得分:2)
wait
表示线程释放锁并进入休眠状态,直到另一个线程通知它。 notifyAll
表示线程告知等待当前同步块中使用的锁的所有其他线程唤醒并尝试再次获取锁。您的代码示例没有任何多线程尝试获取相同锁的情况,因此使用wait和notifyAll在这里没有任何意义。一旦调用等待,就没有什么可以唤醒线程。
等待和通知的一个典型用法:您可能有许多生产者将东西放入队列,而消费者线程则将东西从队列中取出。队列具有消费者调用的take方法,如果队列为空,则它调用wait并且消费者阻塞。该队列有一个put方法,当某些东西进入队列时调用notifyAll,以便唤醒任何等待的消费者线程。
Java教程中有a producer-consumer example of using wait and notifyAll。
答案 1 :(得分:1)
每个线程都在等待它自己的实例,这就是为什么它们都被卡在一个地方。
如果您有private static Object LOCK = new Object();
并且调用LOCK.wait();和LOCK.notify();这可能是另一个故事。
我还怀疑access()方法的synchronized修饰符。它只是在描述的情况下没有用。我最好修改synchronized块中的“canAccess”变量。