zoukankan      html  css  js  c++  java
  • J.U.C之LockSupport

    一、与wait/notify区别

    ​ wait/notify 为Object中的方法,在调用这两个方法前必须要先获得对象的锁,而locksupport则无需获取对象锁就可以锁定指定线程。

    ​ nodify 只能唤醒任意线程,而locksupport 可以唤醒指定线程,且park不需要捕获中断异常,wait 需要。

    二、怎么用

    ​ 主要是park/unpark, park字面意思停车,形象解释为叫这个线程你站住,你停一下。unpark 就是你继续走。park 和 unpark 就是一个消耗许可和产生许可的过程。底层维护了一个计数器_counter, 多次调用unpark 只会多次将_counter置为1,而不是加1,简单说就是:线程A连续调用两次LockSupport.unpark(B)方法唤醒线程B,然后线程B调用两次LockSupport.park()方法, 线程B依旧会被阻塞。因为两次unpark调用效果跟一次调用一样,只能让线程B的第一次调用park方法不被阻塞,第二次调用依旧会阻塞。每一个线程都会维护着这样一个许可.

    public static void park() {
        UNSAFE.park(false, 0L);
    }
    
    public static void unpark(Thread thread) {
        if (thread != null)
            UNSAFE.unpark(thread);
    }
    
    public static void park(Object blocker); // 暂停当前线程
    public static void parkNanos(Object blocker, long nanos); // 暂停当前线程,不过有超时时间的限制
    public static void parkUntil(Object blocker, long deadline); // 暂停当前线程,直到某个时间
    public static void park(); // 无期限暂停当前线程
    public static void parkNanos(long nanos); // 暂停当前线程,不过有超时时间的限制
    public static void parkUntil(long deadline); // 暂停当前线程,直到某个时间
    public static void unpark(Thread thread); // 恢复当前线程
    public static Object getBlocker(Thread t);
    
    示例:
    public class LockSupportTest {
    
        public static  class  MyThread extends Thread{
            @Override
            public void run() {
                System.out.println("线程开始等待..");
                LockSupport.park();
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程结束等待..");
            }
        }
        public static  void main(String[] args){
            Thread _t = new MyThread();
            _t.start();
            System.out.println("开始唤醒线程..");
            LockSupport.unpark(_t);
            System.out.println("唤醒线程结束..");
        }
    }
    

    输出:

    开始唤醒线程..
    线程开始等待..
    唤醒线程结束..
    线程结束等待..


    public class LockSupportTest {
    
        public static  class  MyThread extends Thread{
            @Override
            public void run() {
                System.out.println("线程开始等待..");
                System.out.println("第1个park开始...");
                LockSupport.park();
                System.out.println("第1个park结束...");
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("第2个park开始..");
                LockSupport.park();
                System.out.println("第2个park结束..");
                System.out.println("线程结束等待..");
            }
        }
        public static  void main(String[] args){
            Thread _t = new MyThread();
            _t.start();
            System.out.println("开始唤醒线程..");
            LockSupport.unpark(_t);
            LockSupport.unpark(_t);
            System.out.println("唤醒线程结束..");
        }
    }
    

    输出: 可以看出第2个park未能获取到锁,一直等待

    开始唤醒线程..
    线程开始等待..
    第1个park开始...
    唤醒线程结束..
    第1个park结束...
    第2个park开始..

  • 相关阅读:
    解析ASP.NET WebForm和Mvc开发的区别
    relink:在Linux/UNIX平台上relink Oracle软件(转)
    Java开发 Eclipse使用技巧(转)
    职场人生:情商
    RPC
    PLSQL Developer Debug
    uC/OS-III学习2::uC/OS-III LED闪烁实验
    Flex文件读取报错
    C++字节对齐问题
    写可測试的代码
  • 原文地址:https://www.cnblogs.com/oxf5deb3/p/13620424.html
Copyright © 2011-2022 走看看