前言

在前面的文章中,我们介绍了并发工具中的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. 使用PerfView监测.NET程序性能(四):折叠,过滤和时间范围选择

    在上一篇文章中,我们使用了Perfview的分组功能.分组功能旨在对某些函数按照某个格式进行分组,以减少视图中的各种无关函数的数量.但仅有分组还不够,有时我们想将一些函数调用信息按某些条件过滤掉,例如 ...

  2. mysql命令行客户端结果分页浏览

    转载请注明出处:http://xiezhenye.com/2008/06/mysql%e5%91%bd%e4%bb%a4%e8%a1%8c%e5%ae%a2%e6%88%b7%e7%ab%af%e7% ...

  3. MySQL1安装

    ---恢复内容开始--- (1)安装MySQL ①ZIP安装 ②MSI安装(Windows Installer) Ⅰ  先从官网下载 目前选择使用Typical安装↑ 目前不勾选配置选项↑ 找到配置向 ...

  4. C# Argument 'picture' must be a picture that can be used as an Icon

    Scenario: 创建了一个WinForm的小程序,希望将它显示在任务栏,所以在工具栏中的“公共控件”里,拖入NotifyIcon控件—notifyIcon1,这个是程序运行任务栏右侧通知区域图标显 ...

  5. C/S,B/S的应用和区别

    ·C/S——客户/服务器模式 特点:非对等相互作用——即客户与服务器出于不平等的地位 表现在:服务器用有客户所不具备的硬件和软件资源以及运算能力,服务器提供服务,客户请求服务. A.客户端与服务器的数 ...

  6. Spring Boot中使用Flyway来管理数据库版本

    flyway是一个开源的数据库迁移工具.类似于数据库的版本控制工具.flyway的数据库修改文件默认放在resource下的db.migration文件夹中,以V{version_number}__{ ...

  7. Postgres 的 Array 类型

    mysql 不支持 Array 类型 一.Postgres 原生SQL 适用场景:可以用于实现贴标签功能 1.定义 CREATE TABLE "Students" ( name V ...

  8. D12——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D12 20180912内容纲要: 1.数据库介绍 2.RDMS术语 3.MySQL数据库介绍和基本使用 4.MySQL数据类型 5.MySQL常用命令 6.外键 ...

  9. java实现office文件预览

    不知觉就过了这个久了,继上篇java实现文件上传下载后,今天给大家分享一篇java实现的对office文件预览功能. 相信大家在平常的项目中会遇到需要对文件实现预览功能,这里不用下载节省很多事.大家请 ...

  10. POJ 2656

    #include<iostream> #include<stdio.h> using namespace std; int main() { //freopen("a ...