这个类比较简单,是一个静态类,不需要实例化直接使用,底层是通过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源码分析的更多相关文章

  1. Java并发编程-ReentrantLock源码分析

    一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...

  2. Java并发编程 ReentrantLock 源码分析

    ReentrantLock 一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. 这个类主要基于AQS(Abst ...

  3. Java并发编程-AbstractQueuedSynchronizer源码分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  4. java 并发编程——Thread 源码重新学习

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  5. Java异步编程——深入源码分析FutureTask

    Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...

  6. Java并发-ConcurrentModificationException原因源码分析与解决办法

    一.异常原因与异常源码分析 对集合(List.Set.Map)迭代时对其进行修改就会出现java.util.ConcurrentModificationException异常.这里以ArrayList ...

  7. 并发编程—— FutureTask 源码分析

    1. 前言 当我们在 Java 中使用异步编程的时候,大部分时候,我们都会使用 Future,并且使用线程池的 submit 方法提交一个 Callable 对象.然后调用 Future 的 get ...

  8. 并发编程 —— Timer 源码分析

    前言 在平时的开发中,肯定需要使用定时任务,而 Java 1.3 版本提供了一个 java.util.Timer 定时任务类.今天一起来看看这个类. 1.API 介绍 Timer 相关的有 3 个类: ...

  9. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

随机推荐

  1. Angular 2 + 折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点

    前言 表单在整个系统中的作用相当重要,这里主要扯下响应表单的实现方式. 首先须要操作表单的模块引入这两个模块. import { FormsModule, ReactiveFormsModule } ...

  2. xcode修改项目名后反复出现 clang error

    xcode修改项目名后反复出现 clang error,  提示 ld: file not found . 并且该错误并不是出现在项目编译阶段,而是项目的Tests 的link阶段, 同时提示 xct ...

  3. PHP实现JS的无符号右移(>>>)

    举例: JS: 5>>>2 PHP function uright($a, $n) { $c = 2147483647 >> ($n - 1); return $c &a ...

  4. MongoDB ReplacaSet & Sharding集群安装 配置 和 非集群情况的安装 配置 -摘自网络

    单台机器做sharding --单机配置集群服务(Sharding) --shard1_1 mongod --install --serviceName MongoDBServerShard1 --s ...

  5. [转载]java日志框架log4j详细配置及与slf4j联合使用教程

    一.log4j基本用法 首先,配置log4j的jar,maven工程配置以下依赖,非maven工程从maven仓库下载jar添加到“build path” 1 2 3 4 5 <dependen ...

  6. 【Unity】第7章 输入控制

    分类:Unity.C#.VS2015 创建日期:2016-04-21 一.简介 Unity提供了-个非常易用和强大的用于处理输入信息的类:Input,利用该类可以处理鼠标.键盘.摇杆/方向盘/手柄等游 ...

  7. iOS7相机隐私判断

    转自:http://borissun.iteye.com/blog/1992303 装了iOS7的ip5的隐私设置里多了相机这一项(ip4装iOS7就没有). 如果隐私里把你的app对应的相机给关了, ...

  8. DatePicker的分割线颜色设置

    /** * * 设置时间选择器的分割线颜色 * @param datePicker */ private void setDatePickerDividerColor(DatePicker dateP ...

  9. UVa 10697 - Firemen barracks

    题目:已知三点.求到三点距离同样的点. 分析:计算几何.分三类情况讨论: 1.三点共线,不成立. 2.多点重叠,有多组解. 3.是三角形,输出中点. 说明:注意绝对值小于0.05的按0计算:负数的四舍 ...

  10. (原创)舌尖上的c++--相逢

    引子 前些时候,我在群里出了一道题目:将变参的类型连接在一起作为字符串并返回出来,要求只用函数实现,不能借助于结构体实现.用结构体来实现比较简单: template<typename... Ar ...