前言

在前面的文章中,我们介绍了并发工具中的4个,Samephore,CyclicBarrier,CountDownLatch,Exchanger,但是我们漏了一个,非常的好用的工具,楼主在这里必须加上。

LockSupport

LockSupport 是一个非常方便实用的线程阻塞工具,他可以在任意位置让线程阻塞。并且是静态的方法。是不是很心动?

LockSupport 的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos(),parkUntil()等,他们实现了一个限时的等待。

同样的,有阻塞的方法,当然有唤醒的方法,什么呢?unpark(Thread) 方法。该方法可以将指定线程唤醒。

我们还是来一个例子吧,看看到底有多好用:


public class LockSupportInterruptDemo { static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2"); static class ChangeObjectThread extends Thread { public ChangeObjectThread(String name) {
super.setName(name);
} public void run() {
synchronized (u) {
System.out.println("in " + getName());
// wait
LockSupport.park();
if (Thread.interrupted()) {
System.err.println(getName() + "被中断了");
}
}
System.out.println(getName() + "执行结束了");
}
} public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(3000); t1.interrupt();
// notify
LockSupport.unpark(t2);
} }

执行结果:

完全实现了 wait notify 的功能,但是,请注意,park 方法和 wait 方法相比,不需要获取某个对象的锁,也不会抛出 InterruptedException 异常,因此,你需要像我们的例子一样,使用静态方法进行判断。

如果你将 park 方法改成 park(this)/park(Thread),那么在打印 线程dump 信息的时候会打印阻塞对象的详细信息。

该方法和 Lock 接口一样都是使用的 sun.misc.Unsafe 的 park 方法实现的阻塞。

还有一个需要注意的是:park 方法和 unpark 方法执行顺序不是那么的严格。比如我们在 Thread 类中提到的 suspend 方法 和resume 方法,如果顺序错误,将导致永远无法唤醒,但 park 方法和 unpark 方法则不会,我们测试一下,将 unpark 方法紧跟着 start 方法后面执行,那么也就是说,unpark 方法在 线程2 的park 方法之前执行,但结果相同。

我们将 unpark 方法移动到了 start 方法后面,依然正确执行。

什么原因呢?这是因为 LockSupport 使用了类似信号量的机制。他为每一个线程准备了一个许可(默认不可用),如果许可能用,那么 park 函数会立即返回,并且消费这个许可(也就是将许可变为不可用),如果许可不可用,将会阻塞。而 unpark 方法则使得一个许可变为可用(但是和信号量不同的是,许可不能累加,你不可能拥有超过要给许可,他永远只有一个)。

下面是JDK文档:

这个特定使得:即使 unpark 方法在 park 方法之前执行,他也可以使下一次的 park 操作立即返回。这也使上面的代码能正确执行的原因。

好了,到这里,LockSupport 就介绍完了,可以说,该方法可以替代 wait ,notify ,Condition 的 await ,signal 方法。注意,这里的 park 方法底层和 Lock 的底层实现是一致的。都是掉哟个 sun.misc.Unsafe。这个类可以说很牛逼。

good luck !!!!

并发编程之 线程协作工具 LockSupport的更多相关文章

  1. Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  2. Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

  3. 19、Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  4. Java并发编程:线程控制

    在上一篇文章中(Java并发编程:线程的基本状态)我们介绍了线程状态的 5 种基本状态以及线程的声明周期.这篇文章将深入讲解Java如何对线程进行状态控制,比如:如何将一个线程从一个状态转到另一个状态 ...

  5. python并发编程之线程/协程

    python并发编程之线程/协程 part 4: 异步阻塞例子与生产者消费者模型 同步阻塞 调用函数必须等待结果\cpu没工作input sleep recv accept connect get 同 ...

  6. Java并发编程:线程池的使用

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  7. 并发编程 13—— 线程池的使用 之 配置ThreadPoolExecutor 和 饱和策略

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  8. Scala 深入浅出实战经典 第68讲:Scala并发编程原生线程Actor、Cass Class下的消息传递和偏函数实战解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

  9. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

随机推荐

  1. HyperServer 中的 SSL 支持

    HyperServer 中的 SSL 支持 DLL 模式不需要 SSL 配置, 因为 web 服务器 (如 IIS) 将承担 ssl 配置和 ssl 证书的责任. 对于独立和服务模式, ssl 配置是 ...

  2. [ASE][Daily Scrum]11.11

    各位1111快乐,不知道大家的卡上还剩多少钱啊~~~ TCP server目前遇到一点小瓶颈,不过server的两个人承诺说明天就可以搞定,给他们加油!~! 今天的plan~ View Shilin ...

  3. linux上安装python2.7.11

    好久不玩儿linux了,本来就不熟,现在几乎白痴.步骤如下: 从python官网上下载python的源代码 tar zvxf后得到一个文件夹: 进入Python-2.7.11,按照https://do ...

  4. C# 对象转XML 支持匿名类

    在网上找了很多关于对象转XML的,大多不支持匿名类转换,今天在stackoverflow找了一篇文章  但是有些许BUG  已经修复 public static class ObjectToXML { ...

  5. 迁移桌面程序到MS Store(7)——APPX + Service

    本篇我们以一个Sample工程,来说明如何把一个常见结构的desktop application,转制成APPX并在MS Store提供下载. 之前的篇章中,我们已经介绍了一些内容,包括如何通过Vis ...

  6. AWD比赛常规套路

    作者:Leafer   本文属于Arctic shell原创内容计划文章,转载请注明原文地址! 比赛环境:纯净win10,最新版kali,securecrt或者WinSCP 在进入服务器后应进行的常规 ...

  7. [JavaScript] 跳出循环方法总结

    1.forEach() 方法对数组的每个元素执行一次提供的函数.但是没有办法中止或者跳出 forEach 循环,除了抛出一个异常,该方法没有返回值,return/return false/return ...

  8. linux下时间问题---date

    显示日期 显示日期和时间

  9. python之ETL数据清洗案例源代码

    #python语言 import pandas as pd import time data = pd.read_excel('ETL_数据清洗挑战.xlsx','测试数据',dtype=str)#读 ...

  10. Java Web(四) 一次性验证码的代码实现

    其实实现代码的逻辑非常简单,真的超级超级简单. 1.在登录页面上login.jsp将验证码图片使用标签<img src="xxx">将绘制验证码图片的url给它 2.在 ...