zoukankan      html  css  js  c++  java
  • Java并发编程 LockSupport源码分析

    这个类比较简单,是一个静态类,不需要实例化直接使用,底层是通过java未开源的Unsafe直接调用底层操作系统来完成对线程的阻塞。

     1 package java.util.concurrent.locks;
     2 import java.util.concurrent.*;
     3 import sun.misc.Unsafe;
     4 
     5 
     6 public class LockSupport {
     7     private LockSupport() {}
     8 
     9     //这个类是java未开源的类,直接调用底层操作系统
    10     private static final Unsafe unsafe = Unsafe.getUnsafe();
    11     //记录线程对象中parkBlocker字段的位置
    12     private static final long parkBlockerOffset;
    13 
    14     static {
    15         try {
    16             parkBlockerOffset = unsafe.objectFieldOffset
    17                 (java.lang.Thread.class.getDeclaredField("parkBlocker"));
    18         } catch (Exception ex) { throw new Error(ex); }
    19     }
    20 
    21     private static void setBlocker(Thread t, Object arg) {
    22         // Even though volatile, hotspot doesn't need a write barrier here.
    23         //将org设置到线程的parkBlocker字段上
    24         //这样方便在测试的时候知道线程在什么地方阻塞
    25         unsafe.putObject(t, parkBlockerOffset, arg);
    26     }
    27 
    28     //调用底层操作系统解锁线程
    29     public static void unpark(Thread thread) {
    30         if (thread != null)
    31             unsafe.unpark(thread);
    32     }
    33 
    34     //设置blocker并且锁定线程
    35     public static void park(Object blocker) {
    36         Thread t = Thread.currentThread();
    37         setBlocker(t, blocker);
    38         unsafe.park(false, 0L);
    39         setBlocker(t, null);
    40     }
    41 
    42     //设置blocker并且并且阻塞线程nanos纳秒 可以这么转换成毫秒
    43     //TimeUnit timeUnit = TimeUnit.MILLISECONDS;
    44     //LockSupport.parkNanos(timeUnit.toNanos(3000));
    45     public static void parkNanos(Object blocker, long nanos) {
    46         if (nanos > 0) {
    47             Thread t = Thread.currentThread();
    48             setBlocker(t, blocker);
    49             unsafe.park(false, nanos);
    50             setBlocker(t, null);
    51         }
    52     }
    53 
    54     //设置blocker并且阻塞线程多少毫秒
    55     //注意这里的时间需要使用系统时间加上需要等待的时间
    56     //LockSupport.parkUntil(System.currentTimeMillis() + 3000);
    57     public static void parkUntil(Object blocker, long deadline) {
    58         Thread t = Thread.currentThread();
    59         setBlocker(t, blocker);
    60         unsafe.park(true, deadline);
    61         setBlocker(t, null);
    62     }
    63 
    64     //获得线程阻塞时设置的Blocker
    65     public static Object getBlocker(Thread t) {
    66         if (t == null)
    67             throw new NullPointerException();
    68         return unsafe.getObjectVolatile(t, parkBlockerOffset);
    69     }
    70 
    71     //阻塞线程
    72     public static void park() {
    73         unsafe.park(false, 0L);
    74     }
    75 
    76     public static void parkNanos(long nanos) {
    77         if (nanos > 0)
    78             unsafe.park(false, nanos);
    79     }
    80 
    81     public static void parkUntil(long deadline) {
    82         unsafe.park(true, deadline);
    83     }
    84 }

    写一个简单DEMO,这个类使用起来也很简单,一般很少直接使用,java.util.concurrent包里有很多锁的实现都是基于此类,后续我们会讲到。

     1     public static void main(String[] args) {
     2         
     3         final Thread mainThread = Thread.currentThread();
     4         
     5         Thread thread = new Thread(new Runnable() {
     6             @Override
     7             public void run() {
     8                 System.out.println("3秒后解锁主线程");
     9                 try {
    10                     Thread.sleep(3000);
    11                     LockSupport.unpark(mainThread);
    12                 } catch (InterruptedException e) {
    13                     e.printStackTrace();
    14                 }
    15             }
    16         });
    17         thread.start();
    18         LockSupport.park();
    19         
    20         System.out.println("Demo.main()");
    21     }
  • 相关阅读:
    mybatis学习坑路
    一文理解class.getClassLoader().getResourceAsStream(file)和class.getResourceAsStream(file)区别
    servlet的坑
    class.getResource()方法的更新 坑
    utf8和字节数组的转换
    finally模块的各种情况
    C++ 动态对象数组的知识总结
    Notepad++正则表达式语法
    诸子百家55句
    给初始化为NULL的结构体指针赋值报错问题
  • 原文地址:https://www.cnblogs.com/daxin/p/3831403.html
Copyright © 2011-2022 走看看