Java并发编程 LockSupport源码分析
2023-09-11 14:16:57 时间
这个类比较简单,是一个静态类,不需要实例化直接使用,底层是通过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 }
相关文章
- Unity手游之路<三> 基于Unity+Java的聊天室源码
- Java实现 LeetCode 823 带因子的二叉树(DP)
- Java实现 LeetCode 733 图像渲染(DFS)
- Java实现蓝桥杯VIP算法训练 石子游戏
- java实现第六届蓝桥杯奇怪的数列
- 图解 Java IO : 一、File源码
- java中的==、equals()、hashCode()源码分析
- 【JAVA】 02-Java对象细节
- java集合框架08——HashMap和源码分析
- 【Java】java使用反射访问对象方法和成员变量
- Java源码解读--CopyOnWriteList写时复制集合容器
- 从源码角度详解Java的Callable接口
- 【Java】java 性能监控及工具
- [Java 8 HashMap 详解系列]3.HashMap 的 put() 方法执行原理
- Java 使用 poi 导出Excel 源码完整示例
- 【JAVA】【NIO】5、Java NIO Scatter / Gather
- JAVA语言之Java 中不同的并行实现的性能比较
- java面试题:Linux
- 【JAVA面试必会】JMM高并发详解(java内存模型、JMM三大特征、volatile关键字 )
- Java:openjdk: error: Student is abstract; cannot be instantiated;java编译环境
- Java 读写锁 ReentrantReadWriteLock 源码分析
- ZZNUOJ_用Java编写程序实现1598:找倍数(附源码)
- ZZNUOJ_用Java编写程序实现1800:6-3判定字符位置(附源码)
- 【java】Java并发编程系列- volatile关键字(高并发中特实用哦)
- 【java】Java 内存模型
- Java中保证线程安全的三板斧