• 线程通信的三方方式(线程唤醒)


    文章中的Console.log()使用的是 hutool工具

    • 方式1和方式2,必须搭配锁使用,而方式3可以不使用锁

    1、使用wait notify synchronized 实现线程唤醒机制

    实现线程唤醒机制,但不保证是精确唤醒

    private static void imp1() {
        final Object lock = new Object();
        new Thread(() -> {
            synchronized (lock) {
                Console.log("{} 开始等待...", Thread.currentThread().getName());
                try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}
                Console.log("{} 被唤醒", Thread.currentThread().getName());
            }
        }, "线程1").start();
    
        new Thread(() -> {
            synchronized (lock) {
                try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
                Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
                lock.notify();
            }
        }, "线程2").start();
    }
    

    2、使用 ReentrantLock,Conditionawaitsignal方法

    可以实现精确唤醒

    private static void imp2() {
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(() -> {
            lock.lock();
            try {
                Console.log("{} 开始等待...", Thread.currentThread().getName());
                condition.await();
                Console.log("{} 被唤醒", Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "线程1").start();
    
        new Thread(() -> {
            lock.lock();
            try {
                TimeUnit.SECONDS.sleep(1);
                Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
                condition.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
        }, "线程2").start();
    }
    

    3、使用 LockSupportpark(),unpark(线程1)方法

    可以实现精确唤醒

    注意下面休眠位置unpark 可以在 park 之前执行,这样 t1线程在执行到park处的时候,不会阻塞

        private static void imp3() {
            Thread t1 = new Thread(() -> {
                try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
                Console.log("{} 开始等待...LockSupport", Thread.currentThread().getName());
                LockSupport.park();
                Console.log("{} 被唤醒", Thread.currentThread().getName());
            }, "线程1");
    
            t1.start();
    
            Thread t2 = new Thread(() -> {
                Console.log("{} 执行唤醒操作", Thread.currentThread().getName());
                LockSupport.unpark(t1);
            }, "线程2");
            t2.start();
        }
    

    本文来自博客园,作者:祖国滴粑粑花,转载请注明原文链接:https://www.cnblogs.com/rxx1005/p/15780022.html

  • 相关阅读:
    char与byte的区别
    java 中的枚举类型
    * .mesh 体网格文件解析
    java 中的equals hashCode
    java 中的 hashCode()
    java 中的判断两个对象是否相等的比较严格的操作
    java 中的访问限制
    数学建模 投资模型
    java abstract
    java 中的多态 & 动态绑定
  • 原文地址:https://www.cnblogs.com/rxx1005/p/15780022.html
Copyright © 2020-2023  润新知