在AQS里面进行阻塞线程,解除阻塞线程就用的LockSupport。

JDK1.8源码:

package java.util.concurrent.locks;
import sun.misc.Unsafe; public class LockSupport {
private LockSupport() {} // Cannot be instantiated. private static void setBlocker(Thread t, Object arg) {
// Even though volatile, hotspot doesn't need a write barrier here.
UNSAFE.putObject(t, parkBlockerOffset, arg);
} public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
} public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
} 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);
}
} public static void parkUntil(Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(true, deadline);
setBlocker(t, null);
} 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);
} static final int nextSecondarySeed() {
int r;
Thread t = Thread.currentThread();
if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
r ^= r << 13; // xorshift
r ^= r >>> 17;
r ^= r << 5;
}
else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
r = 1; // avoid zero
UNSAFE.putInt(t, SECONDARY, r);
return r;
} // Hotspot implementation via intrinsics API
private static final sun.misc.Unsafe UNSAFE;
private static final long parkBlockerOffset;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;
parkBlockerOffset = UNSAFE.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
SEED = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSeed"));
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception ex) { throw new Error(ex); }
}
}

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。 
LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark()不会遇到“Thread.suspend 和 Thread.resume所可能引发的死锁”问题。
因为park() 和 unpark()有许可的存在;调用 park() 的线程和另一个试图将其 unpark() 的线程之间的竞争将保持活性。

方法列表:

// 返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。
static Object getBlocker(Thread t)
// 为了线程调度,禁用当前线程,除非许可可用。
static void park()
// 为了线程调度,在许可可用之前禁用当前线程。
static void park(Object blocker)
// 为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。
static void parkNanos(long nanos)
// 为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。
static void parkNanos(Object blocker, long nanos)
// 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
static void parkUntil(long deadline)
// 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
static void parkUntil(Object blocker, long deadline)
// 如果给定线程的许可尚不可用,则使其可用。
static void unpark(Thread thread)

demo:

import java.util.concurrent.locks.LockSupport;

public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread = Thread.currentThread();
LockSupport.unpark(thread);
LockSupport.park();
System.out.println("b");
}
}

结果为b,先释放许可,再获取许可,主线程能够正常终止。LockSupport许可的获取和释放,一般来说是对应的,如果多次unpark,只有一次park也不会出现什么问题,结果是许可处于可用状态。

import java.util.concurrent.locks.LockSupport;

public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread = Thread.currentThread();
LockSupport.unpark(thread);
System.out.println("a");
LockSupport.park();
System.out.println("b");
LockSupport.park();
System.out.println("c");
}
}
a
b

LockSupport是不重入的,如果一个线程连续2次调用LockSupport.park(),那么该线程一定会一直阻塞下去。

import java.util.concurrent.locks.LockSupport;

public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable()
{
private int count = 0;
@Override
public void run()
{
System.out.println("start");
long start = System.currentTimeMillis();
long end = 0;
while ((end - start) <= 1000)
{
count++;
end = System.currentTimeMillis();
}
System.out.println("after 1 second.count=" + count);
//等待或许许可
LockSupport.park();
System.out.println("thread over." + Thread.currentThread().isInterrupted()); }
});
t.start();
Thread.sleep(2000);
// 中断线程
t.interrupt();
System.out.println("main over");
}
}
start
after 1 second.count=73186612
main over
thread over.true

最终线程会打印出thread over.true。这说明线程如果因为调用park而阻塞的话,能够响应中断请求(中断状态被设置成true),但是不会抛出InterruptedException

park和wait的区别:wait让线程阻塞前,必须通过synchronized获取同步锁。

总结起来LockSupport有以下不同和特点:
其实现机制和wait/notify有所不同,面向的是线程。
不需要依赖监视器
与wait/notify没有交集
使用起来更加灵活方便

http://www.cnblogs.com/skywang12345/p/3505784.html

https://my.oschina.net/readjava/blog/282882

http://blog.csdn.net/aitangyong/article/details/38373137?utm_source=tuicool&utm_medium=referral

https://www.zhihu.com/question/26471972

http://blog.csdn.net/opensure/article/details/53349698

Java多线程 LockSupport的更多相关文章

  1. Java多线程系列--“JUC锁”07之 LockSupport

    概述 本章介绍JUC(java.util.concurrent)包中的LockSupport.内容包括:LockSupport介绍LockSupport函数列表LockSupport参考代码(基于JD ...

  2. Java多线程系列——线程阻塞工具类LockSupport

    简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执 ...

  3. Java多线程系列--AQS之 LockSupport

    concurrent包是基于AQS (AbstractQueuedSynchronizer)框架的,AQS(JAVA CAS原理.unsafe.AQS)框架借助于两个类: Unsafe(提供CAS操作 ...

  4. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  5. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  6. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

  7. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例

    概要 本章介绍JUC包中的CyclicBarrier锁.内容包括:CyclicBarrier简介CyclicBarrier数据结构CyclicBarrier源码分析(基于JDK1.7.0_40)Cyc ...

  8. Java多线程系列--“JUC锁”01之 框架

    本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...

  9. Java多线程系列目录(共43篇)

    最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...

随机推荐

  1. 洛谷 P1092 虫食算 Label:dfs

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  2. js中的this关键字详解

    this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, 复制代码 代码如下: function test(){ this.x = 1; ...

  3. URAL 1658. Sum of Digits(DP)

    题目链接 隔了一年零三个月,重新刷URAL,这题挺麻烦的输出路径.输出路径挺扯的,乱写了写乱改改就A了...我本来想用很靠谱,记录每一条路径的,然后输出最小的,结果Tle,然后我使劲水水又过了一组,发 ...

  4. 二 、打开地图《苹果iOS实例编程入门教程》

    该app为应用的功能为给你的iPhone打开google地图有效地址连接 现版本 SDK 8.4 Xcode 运行Xcode 选择 Create a new Xcode project ->Si ...

  5. 最新Velocity使用和Velocity语法

    Velocity语法 Velocity的使用要用到下面几个包,可以从官网下载,commons-collections.jar,velocity-1.4.jar,velocity-dept.jar; 1 ...

  6. Nodejs Http发送post请求

    Nodejs  Http发送post请求 var http = require('http'); function epay(params) { console.log(" COME IN& ...

  7. .net的五层架构

    原文章地址是http://www.360doc.com/content/11/1210/21/19147_171335782.shtml 我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经 ...

  8. select在各个浏览器中的兼容性问题

    我们知道select标签在各个浏览器中的属性和各浏览器的支持各有些不同,从而造成select选择框在各浏览器的显示有不同. 下面我们通过对主要CSS属性的支持,打造全兼容select. 对select ...

  9. android-BaseAdapter自定义控件深刻理解

    一.自定义控件的实现 自定义控件需要继承BaseAdapter抽象类,该类实现了ListAdapter, SpinnerAdapter两个接口,这两个接口继承了Adapter接口类,没错.是继承Ada ...

  10. JAVA中保留指定小数位方法

    import java.math.BigDecimal;    import java.text.DecimalFormat;    import java.text.NumberFormat;    ...