Java wait和notify/notifyAll的使用方法

2020-12-22 16:29:17 浏览数 (1)

java的wait/notify的通知机制可以用来实现线程间通信。wait表示线程的等待,调用该方法会导致线程阻塞,直至另一线程调用notify或notifyAll方法才唤醒它后继续执行。

注意事项

  1. wait和notify/notifyAll操作的对象需是synchronized锁持有对象。
  2. notify随机唤醒一个,notifyAll全部唤醒。
  3. 在锁持有对象调用wait进行等待时,会释放锁。
  4. lock.notifyAll重新获取锁之后,同样遵循synchronized同步执行。

1. 样例代码

代码语言:javascript复制
import java.time.LocalTime;

public class MainTest {

    private static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Main start "   LocalTime.now());
        Thread thread = new Thread(new MyThread());
        thread.start();

        Thread thread2 = new Thread(new MyThread());
        thread2.start();

        System.out.println("Main sleep 5s "   LocalTime.now());
        Thread.sleep(5000);
        System.out.println("Main try to get lock... "   LocalTime.now());
        synchronized(lock){
            System.out.println("Main get lock and notifyAll "   LocalTime.now());
            lock.notifyAll();
        }

        System.out.println("Main end");
    }

    public static class MyThread implements Runnable{

        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName   " run and try to get lock... "   LocalTime.now());
            synchronized (lock){
                System.out.println(threadName   " get lock and sleep 2s... "   LocalTime.now());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(threadName   " wait "   LocalTime.now());
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(threadName   " get lock agein and sleep 2s "   LocalTime.now());

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(threadName   " end "   LocalTime.now());
        }
    }
}

2. 输出结果

代码语言:javascript复制
Main start 17:55:13.788
Main sleep 5s 17:55:13.789
Thread-0 run and try to get lock... 17:55:13.790
Thread-1 run and try to get lock... 17:55:13.790
Thread-0 get lock and sleep 2s... 17:55:13.790
Thread-0 wait 17:55:15.791
Thread-1 get lock and sleep 2s... 17:55:15.791
Thread-1 wait 17:55:17.791
Main try to get lock... 17:55:18.789
Main get lock and notifyAll 17:55:18.789
Main end
Thread-1 get lock agein and sleep 2s 17:55:18.789
Thread-1 end 17:55:20.790
Thread-0 get lock agein and sleep 2s 17:55:20.790
Thread-0 end 17:55:22.791

3. 流程示意图

image.png

0 人点赞