线程通信

1.notify、wait、notifyall

notify方法是唤醒一个被阻塞的线程,若有多个线程被阻塞,先唤醒优先级高的

notifyall是唤醒所有线程

wait是阻塞一个线程,该线程阻塞后会释放锁

这三个方法必须在同步代码块或者同步方法中使用,并且调用者必须是同步代码块或者同步方法的同步监视器

实现1~100线程1、2的轮流打印

package Test1;

/**
 * @author rook1e
 * @creat 2022/1/12
 */

class Number 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++;
                } else {
                    break;
                }

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

public class ComTest {
    public static void main(String[] args) {
        Number number = new Number();
        Thread t1 = new Thread(number);
        Thread t2 = new Thread(number);

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

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

这段代码有以下几个很值得注意的点

0.synchronized(this) 只new了一个Number对象,并且线程共用一个numer对象,所以对象是唯一的,所以当前对象this也是唯一的,因此锁唯一。

1.notify唤醒线程后,不会出现线程安全问题吗?答案是不会,当线程1打印完1后阻塞,线程2拿到同步锁,进入同步代码块,唤醒线程1,但此时线程2已经拿到同步锁,线程1无法进入同步代码块,也就没有线程安全问题

2.使用wait方法后,线程会失去同步锁,线程进入阻塞状态

 

sleep() 和 wait()的异同

相同点:一旦使用会让线程进入阻塞状态

不同点:1.声明位置不同,Thread类中声明sleep()方法,Object类中声明wait()方法

    2.调用要求不同,sleep方法可以在任何需要的场景下调用,wait方法只能使用在同步代码块或者同步方法中

    3.使用结果不同,sleep方法不会释放同步监视器(锁),wait方法使用后会释放同步监视器。

 

posted @ 2022-01-12 15:56  Rook1e  阅读(57)  评论(0编辑  收藏  举报