8.3.线程间通信

1.案例:两个打印机交替打印

class Communication implements Runnable{
    private int i=1;
//    private final ReentrantLock lock=new ReentrantLock();
    @Override
    public void run(){
        while(true){
            synchronized(this){
//                lock.lock();//java.lang.IllegalMonitorStateException 锁不一致报错
                notify();//唤醒其他一个进程
                try {
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(i<=100)
                {
                    System.out.println(Thread.currentThread().getName()+":"+i);
                    i++;
                }else
                {
                    break;
                }
                try {
                    wait();//阻塞
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
public class CommunicationTest {
    public static void main(String[] args) {
        Communication com = new Communication();
        Thread t1 = new Thread(com);
        Thread t2 = new Thread(com);
        t1.setName("打印机1");
        t2.setName("打印机2");
        t1.start();
        t2.start();
    }
}

2.线程间通信涉及到的三个方法

wait():一旦执行此方法,当前进程进入阻塞状态,并释放同步监视器
notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait(),就唤醒优先级高的那个。
notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。

说明:
1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
否则,会出现IllegalMonitorStateException异常
3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。

sleep()与wait()的异同?

相同点:一旦执行方法,都可以使当前进程进入阻塞状态。
不同点:
1:两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
2:调用的要求不同:sleep()可以在任何需要的场景下调用。wait()必须使用在同步代码块或者同步方法中
3:关于是否释放同步监视器:如果两个方法都使用在同步代码块或者同步方法中,sleep()不会释放锁,而wait()会释放锁
posted @ 2021-04-16 16:01  袁中  阅读(35)  评论(0编辑  收藏  举报