zoukankan      html  css  js  c++  java
  • 线程通信的三方方式(线程唤醒)

    文章中的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

  • 相关阅读:
    P4995 跳跳!
    P4306 [JSOI2010]连通数
    P1339 [USACO09OCT]热浪Heat Wave
    P2002 消息扩散
    P3388 【模板】割点(割顶)
    P1656 炸铁路
    P2863 [USACO06JAN]牛的舞会The Cow Prom
    P1516 青蛙的约会
    3.从尾到头打印链表
    2.替换空格
  • 原文地址:https://www.cnblogs.com/rxx1005/p/15780022.html
Copyright © 2011-2022 走看看