您的位置 首页 java

java 线程间简单通信,wait()\notify()使用实例

线程间通信,平时用到的并不多,但是理解其原理对多线程编程有很大的好处。这里编写了几个很简单的例子。

使用wait()和notify()注意

1、需要在 synchronized 包裹的代码块中。

2、wait()可以指定时间,如果没有,可能会导致线程一直等待。

样例:

 @Slf4j
public class ThreadCommunicate {

    public static void main(String[] args) {
        ThreadCommunicate threadCommunicate = new ThreadCommunicate();
//        //没有synchronized包裹的wait会报错
//        threadCommunicate.waitTest1();
//        //我等到永远,所以要注掉,不然下面没法走了
//        threadCommunicate.waitTest2();
//        //我等你5s
        threadCommunicate.waitTest3();
//        //没有synchronized包裹的notify会报错
        threadCommunicate.notifyTest();
//        //白雪公主与白马王子之间有一个电话
        threadCommunicate.havePhone(threadCommunicate);

    }

    /**
     * wait 需要在synchronized中才能正常使用
     */    public void waitTest1(){

        log.info("白雪公主没给发出自己的地址,等待着王子的到来,会报错的。");
        try {
            wait();
        } catch (Exception e) {
            log.error("wait 必须在synchronized的包裹下,才能正常使用");
        }
    }

    /**
     * 无限等待
     * synchronized 它可以把任意一个非 NULL 的对象当作锁。
     *属于独占式的悲观锁,同时属于可重 入锁
     */    public  synchronized void waitTest2(){

        log.info("增加了synchronized,wait方法会把当前调用线程阻塞。相当于自己打晕了自己,给别人机会,当前 线程 是{}!" +
                "可以看到系统一直处于运行状态无法停止,就像白雪公主永远等不到她的白马王子。",Thread.currentThread().getName());
        try {
            wait();
        } catch (Exception e) {
            log.info("wait 必须在synchronized的包裹下,才能正常使用");
            e.printStackTrace();
        }
    }

    /**
     * 等你5s
     */    public synchronized void waitTest3(){
        log.info("为了不永远的等待,这份约定增加了一个期限,如果5s内,你还没有和我道歉,那咱们就分手吧。当前线程是{}",Thread.currentThread().getName());
        try {
            wait(5000);
        } catch (Exception e) {
            log.info("wait 必须在synchronized的包裹下,才能正常使用");
            e.printStackTrace();
        }
        log.info("5s过去了,白雪公主和白马王子分手了,勿念,祝越来越好。");
    }

    /**
     * 用来当做对象锁
     */    public Object phone1 = new Object();
    /**
     * 在电话1中睡了
     */    public void waitWithPhone(){

        synchronized (phone1){
            log.info("在phone1包裹的synchronized中,白雪公主睡了。当前公主是{}。",Thread.currentThread().getName());
            try {
                phone1.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("白雪公主接到了白马王子的电话,醒了。");
        }
    }

    /**
     * 打电话,吵醒白雪公主
     */    public void notifyWithPhone(){

        synchronized (phone1){
            log.info("在phone1包裹的synchronized中,白马王子来了。当前白马是{}。",Thread.currentThread().getName());
            phone1.notify();
        }
    }

    /**
     * 有电话,两个线程才能通信
     * @param threadCommunicate
     */    public void havePhone(ThreadCommunicate threadCommunicate){
        Thread snowPrincess = new Thread(new Runnable() {
            @ Override 
            public void run() {
                threadCommunicate.waitWithPhone();
            }
        });
        Thread horsePrice = new Thread(new Runnable() {
            @Override
            public void run() {
                threadCommunicate.notifyWithPhone();
            }
        });
        snowPrincess.start();
        try {
            Thread.sleep(100);
            horsePrice.start();
            Thread.sleep(1000);
            log.info("白马王子顺利的通知了白雪公主,两个人过上了幸福的生活");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}  

样例可以直接在一个类文件中运行。

文章来源:智云一二三科技

文章标题:java 线程间简单通信,wait()\notify()使用实例

文章地址:https://www.zhihuclub.com/194030.shtml

关于作者: 智云科技

热门文章

网站地图