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

  • 相关阅读:
    UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
    UVa 1658 (拆点法 最小费用流) Admiral
    UVa 11082 (网络流建模) Matrix Decompressing
    UVa 753 (二分图最大匹配) A Plug for UNIX
    UVa 1451 (数形结合 单调栈) Average
    UVa 1471 (LIS变形) Defense Lines
    UVa 11572 (滑动窗口) Unique Snowflakes
    UVa 1606 (极角排序) Amphiphilic Carbon Molecules
    UVa 11054 Wine trading in Gergovia
    UVa 140 (枚举排列) Bandwidth
  • 原文地址:https://www.cnblogs.com/rxx1005/p/15780022.html
Copyright © 2011-2022 走看看