并发编程[5]_wait和notify


1. wait 和 notify

wait() 方法是Object类中的方法,他的作用是让当前线程进入等待状态,而使用notify() 方法可以唤醒。

image

  • wait(long): void ,参数是毫秒,表示等待毫秒数,直到时间结束或被唤醒;
  • wait(long, int): void ,第一个参数是毫秒,第二个参数是纳秒,如果纳秒在0-999999之间,则第一个参数值+1, 最后调用wait(long) 方法;
  • wait(): void ,调用wait(0) ,表示无限等待。
  • notify(): void,随机唤醒一个正在等待中的线程
  • notifyAll():void ,唤醒所有正在等待中的线程

调用上述方法前,得保证当前线程是此对象的监视器所有者,即要获得对象的锁,否则直接调上述方法,会报出 java.lang.IllegalMonitorStateException 的错误。

简单的例子1:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("wait()");
                        obj.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("唤醒后的操作");
            }
        };
        thread.start();

        Thread.sleep(1000);
        synchronized (obj){
            obj.notify();
            log.debug("唤醒");
        }
    }
}

运行结果:

2021-04-25 22:31:49.151  [thread1] - wait()
2021-04-25 22:31:50.152  [main] - 唤醒
2021-04-25 22:31:50.152  [thread1] - 唤醒后的操作

2. wait 和 sleep

wait 和 sleep 都是可以让线程进入休眠的状态,但是具体的又有很大的不同。

sleep wait
所属类 Thread 类中的静态方法 Object 类中的非静态方法
参数 有参 有参和无参
调用后的线程状态 TIMED_WAITING WAITING(无参时) 或 TIMED_WAITING
不会释放锁 会释放锁
使用场景 任何地方都能使用 需取得锁后,才能调用

例子:
根据运行结果的时间来判断会不会释放锁。
测试sleep不会释放锁:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("sleep(5000) 中...");
                        Thread.sleep(5000);
                    }
                    log.debug("休眠结束...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        Thread.sleep(1000);
        log.debug("线程1:{}",thread1.getState());
        synchronized (obj){
            log.debug("正在访问obj...");
        }
    }
}

运行结果:

2021-04-25 22:55:50.762  [thread1] - sleep(5000) 中...
2021-04-25 22:55:51.762  [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:55.764  [thread1] - 休眠结束...
2021-04-25 22:55:55.764  [main] - 正在访问obj...

测试wait会释放锁:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("wait(5000) 中...");
                        obj.wait(5000);
                    }
                    log.debug("休眠结束...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        Thread.sleep(1000);
        log.debug("线程1:{}",thread1.getState());
        synchronized (obj){
            log.debug("正在访问obj...");
        }
    }
}

运行结果

2021-04-25 22:55:07.307  [thread1] - wait(5000) 中...
2021-04-25 22:55:08.308  [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:08.308  [main] - 正在访问obj...
2021-04-25 22:55:12.308  [thread1] - 休眠结束...
posted @ 2024-08-23 10:49  Aeons  阅读(11)  评论(0编辑  收藏  举报