Java并发编程 LockSupport源码分析
这个类比较简单,是一个静态类,不需要实例化直接使用,底层是通过java未开源的Unsafe直接调用底层操作系统来完成对线程的阻塞。
package java.util.concurrent.locks;
import java.util.concurrent.*;
import sun.misc.Unsafe; public class LockSupport {
private LockSupport() {} //这个类是java未开源的类,直接调用底层操作系统
private static final Unsafe unsafe = Unsafe.getUnsafe();
//记录线程对象中parkBlocker字段的位置
private static final long parkBlockerOffset; static {
try {
parkBlockerOffset = unsafe.objectFieldOffset
(java.lang.Thread.class.getDeclaredField("parkBlocker"));
} catch (Exception ex) { throw new Error(ex); }
} private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
//将org设置到线程的parkBlocker字段上
//这样方便在测试的时候知道线程在什么地方阻塞
unsafe.putObject(t, parkBlockerOffset, arg);
} //调用底层操作系统解锁线程
public static void unpark(Thread thread) {
if (thread != null)
unsafe.unpark(thread);
} //设置blocker并且锁定线程
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(false, 0L);
setBlocker(t, null);
} //设置blocker并且并且阻塞线程nanos纳秒 可以这么转换成毫秒
//TimeUnit timeUnit = TimeUnit.MILLISECONDS;
//LockSupport.parkNanos(timeUnit.toNanos(3000));
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(false, nanos);
setBlocker(t, null);
}
} //设置blocker并且阻塞线程多少毫秒
//注意这里的时间需要使用系统时间加上需要等待的时间
//LockSupport.parkUntil(System.currentTimeMillis() + 3000);
public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
unsafe.park(true, deadline);
setBlocker(t, null);
} //获得线程阻塞时设置的Blocker
public static Object getBlocker(Thread t) {
if (t == null)
throw new NullPointerException();
return unsafe.getObjectVolatile(t, parkBlockerOffset);
} //阻塞线程
public static void park() {
unsafe.park(false, 0L);
} public static void parkNanos(long nanos) {
if (nanos > 0)
unsafe.park(false, nanos);
} public static void parkUntil(long deadline) {
unsafe.park(true, deadline);
}
}
写一个简单DEMO,这个类使用起来也很简单,一般很少直接使用,java.util.concurrent包里有很多锁的实现都是基于此类,后续我们会讲到。
public static void main(String[] args) {
final Thread mainThread = Thread.currentThread();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("3秒后解锁主线程");
try {
Thread.sleep(3000);
LockSupport.unpark(mainThread);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
LockSupport.park();
System.out.println("Demo.main()");
}
Java并发编程 LockSupport源码分析的更多相关文章
- Java并发编程-ReentrantLock源码分析
一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...
- Java并发编程 ReentrantLock 源码分析
ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...
- Java并发编程-AbstractQueuedSynchronizer源码分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- java 并发编程——Thread 源码重新学习
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- Java异步编程——深入源码分析FutureTask
Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...
- Java并发-ConcurrentModificationException原因源码分析与解决办法
一.异常原因与异常源码分析 对集合(List.Set.Map)迭代时对其进行修改就会出现java.util.ConcurrentModificationException异常.这里以ArrayList ...
- 并发编程—— FutureTask 源码分析
1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象.然后调用 Future 的 get ...
- 并发编程 —— Timer 源码分析
前言 在平时的开发中,肯定需要使用定时任务,而 Java 1.3 版本提供了一个 java.util.Timer 定时任务类.今天一起来看看这个类. 1.API 介绍 Timer 相关的有 3 个类: ...
- Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...
随机推荐
- 从sys/power/state分析并实现S3C2416的睡眠和唤醒
环境: PC: debian-7.6.0 ARM CPU: S3C2416 Linux-Kernel: 3.6.0(FriendlyARM) U-boot: 1.3.4 一.问题来源 依据须要,在S3 ...
- java 传址或传值
原文链接: http://blog.csdn.net/jdluojing/article/details/6962893 java是传值还是传址,这个问题已经讨论了很久了,有些人说是传值的,有些人说要 ...
- Java Date and Calendar examples
Java Date and Calendar examples This tutorial shows you how to work with java.util.Date and java.uti ...
- java中使用for遍历集合是注意的空指针异常
public static void main(String[] args) { List<Object> a = null; for(Object i : a)//会有空指针异常 { } ...
- JavaWeb 返回json数据的两种方式
1.说明 由于一般情况下,由浏览器(前端)发送请求,服务器(后台)响应json数据,所以这里结合js进行说明: A服务器发送请求至B服务器,并接收其返回的json数据,见文末推荐,这里不再赘述! 2. ...
- H.264 RTP PAYLOAD 格式
H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +---------------+ |0|1|2|3|4|5|6|7 ...
- libsvm参数说明[zz]
English:libsvm_options:-s svm_type : set type of SVM (default 0) 0 -- C-SVC 1 -- nu-SVC 2 -- one-cla ...
- hibernate中的saveOrUpdate()报错
最近使用hibernate保存数据的时候,没有使用id自增主键,而是使用了一种调用seq以后手动赋值的方式生成主键,然后使用saveorupdate()报错.上网查看终于知道了问题所在,记录一下: 在 ...
- hdu 2680 Choose the best route (dijkstra算法)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2680 /************************************************* ...
- HTML5学习笔记(二十):JavaScript中的标准对象
这里提到的标准对象指ECMAScript中定义的对象,无论JavaScript运行那种环境(浏览器.Node.js)下都存在的对象. typeof 在JavaScript的世界里,一切都是对象. 但是 ...