我上了这个课:

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

10-06 12:57