wait和notify方法的使用

Posted 听风者-better

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wait和notify方法的使用相关的知识,希望对你有一定的参考价值。

wait和notify方法的使用

1.wait 和 notify 均为 Object 的方法

  • Object.wait() —— 暂停一个线程
  • Object.notify() —— 唤醒一个线程

2.使用这两个方法时,我们需要先有一个Object对象,配合synchronize使用
3.wait被执行后,锁自动被释放
notify被执行后,锁不会自动释放,必须执行完notify)方法所在的synchronized代码块后才释放

暂停唤醒实例:

/**
* 奇偶数依次输出
*/

public static final Object lock = new Object();

public static void main(String[] args) throws InterruptedException 
    Thread t1 = new Thread(() -> 
        synchronized (lock) 
            for (int i = 1; i <= 100; i += 2) 
                lock.notify();
                System.out.println("奇数:" + i);
                //大于100后不再wait
                if (i < 100) 
                    try 
                        lock.wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                
            
        
    );
    Thread t2 = new Thread(() -> 
        synchronized (lock) 
            for (int i = 2; i <= 100; i += 2) 
                lock.notify();
                System.out.println("偶数:" + i);
                //等于100后不再wait了
                if (i == 100) 
                    break;
                
                try 
                    lock.wait();
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        
    );
    t1.start();
    Thread.sleep(1000L);
    t2.start();

notify不立即释放锁实例

public static final Object lock = new Object();

public static final List<Integer> list = new ArrayList<>();

public static void main(String[] args) throws InterruptedException 
    Thread t1 = new Thread(() -> 
        synchronized (lock) 
            for (int i = 0; i < 10; i++) 
                list.add(i);
                System.out.println("添加第" + (i + 1) + "个元素");
                if (i == 4) 
                    lock.notify();
                    System.out.println("唤起t2线程");
                
            
        
    );
    Thread t2 = new Thread(() -> 
        synchronized (lock) 
            try 
                lock.wait();
             catch (InterruptedException e) 
                e.printStackTrace();
            
            for (int i = 0; i < 10; i++) 
                System.out.println("获取到元素:" + list.get(i));
            
        
    );
    t2.start();
    Thread.sleep(1000L);
    t1.start();

输出结果


添加第1个元素
添加第2个元素
添加第3个元素
添加第4个元素
添加第5个元素
唤起t2线程
添加第6个元素
添加第7个元素
添加第8个元素
添加第9个元素
添加第10个元素
获取到元素:0
获取到元素:1
获取到元素:2
获取到元素:3
获取到元素:4
获取到元素:5
获取到元素:6
获取到元素:7
获取到元素:8
获取到元素:9

由此可见notify被执行后,没有释放锁,而是执行完synchronize里的代码,再释放锁去执行唤醒的线程

notify和notifyAll

notify会唤醒此Object控制权下的一个处于 wait 状态的线程。若有多个线程处于此 object 控制权下的 wait 状态,只有一个会被唤醒。
notifyAll唤醒所有处于此 object 控制权下的 wait 状态的线程。
如果一个Object对象被多个线程使用时,可以使用notifyAll唤醒全部wait状态线程,具体还要看业务来使用。

以上是关于wait和notify方法的使用的主要内容,如果未能解决你的问题,请参考以下文章

JAVA同步锁机制 wait() notify() notifyAll()

sleep和wait的区别有:

线程中sleep和wait区别

线程sleep 和wait 的区别

Java中wait和sleep方法的区别

java中的sleep()和wait()的区别