线程通信、sleep和wait方法


线程通信

例子

使用两个线程打印1-100。线程1,2交替打印。

要让线程1、2交替打印,就需要使用 wait() 阻塞方法,并且wait方法会释放锁,当另一个线程执行完后调用 notify() notifyAll()`唤醒线程

package com.ljs.java2;

public class CommunicationTest {
    public static void main(String[] args) {
        Communication communication = new Communication();
        Thread t1 = new Thread(communication);
        Thread t2 = new Thread(communication);

        t1.setName("线程1");
        t2.setName("线程2");

        t1.start();
        t2.start();
    }
}

class Communication implements Runnable{

    private int number = 1;

    @Override
    public void run() {
        while (true){
            synchronized (this){
                notify();
                if (number <= 100){
                    System.out.println(Thread.currentThread().getName()+":"+number);
                    number++;

                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else {
                    break;
                }
            }

        }
    }
}
  1. wait():当前线程进入阻塞状态,并释放同步监视器锁

  2. notify(): 唤醒被wait的一个线程,如果有多个线程被wait,就唤醒优先级高的那个

  3. notifyAll(): 唤醒所有被wait的线程

  4. wait() notify() notifyAll() 必须使用在同步代码块或同步方法中

  5. wait() notify() notifyAll() 必须是的调用者必须是同步代码块或同步方法中的同步监视器,

    image-20220803153411016

    否则会报错

image-20220803153433992

或者可以这样:

public void run() {
        while (true){
            synchronized (obj){
                obj.notify();
                if (number <= 100){
                    System.out.println(Thread.currentThread().getName()+":"+number);
                    number++;

                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }else {
                    break;
                }
            }

        }
    }

wait()和sleep()的异同

  • 两者最主要的区别在于:**sleep() 方法没有释放锁,而 wait() 方法释放了锁** 。

  • 两者都可以暂停线程的执行。

  • wait() 通常被用于线程间交互/通信,sleep() 通常被用于暂停执行。

  • wait() 方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify() 或者 notifyAll() 方法。sleep() 方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout) 超时后线程会自动苏醒。

    来源:《Javaguide》说说 sleep() 方法和 wait() 方法区别和共同点?


Author: qwq小小舒
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source qwq小小舒 !
  TOC