Java并发实现线程阻塞原语LockSupport
LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现。LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。
1、LockSupport原理
LockSupport是只有静态方法且构造函数私有,对外给线程提供各种版本的park()和unpark()方法实现阻塞线程和解除线程阻塞。
LockSupport和每个使用它的线程都与一个许可(permit)关联。permit类似信号量,相当于1,0的开关,默认是0,调用一次unpark被置为1,调用一次park会消费permit, 也就是将1变成0,同时park立即返回。再次调用park会变成block(因为permit为0了,会阻塞在这里,直到permit变为1), 这时调用unpark会把permit置为1。每个线程都有一个相关的permit, permit最多只有一个,重复调用unpark也不会积累。
park()和unpark()不会有 “Thread.suspend和Thread.resume所可能引发的死锁” 问题,由于许可的存在,调用 park 的线程和另一个试图将其 unpark 的线程之间的竞争将保持活性。
如果调用线程被中断,则park方法会返回。同时park也拥有可以设置超时时间的版本。
需要特别注意的一点:park 方法还可以在其他任何时间“毫无理由”地返回,因此通常必须在重新检查返回条件的循环里调用此方法。从这个意义上说,park 是“忙碌等待”的一种优化,它不会浪费这么多的时间进行自旋,但是必须将它与 unpark 配对使用才更高效。
2、LockSupport与Object的wait/notify对比
在Java6引入LockSupport以前,线程挂起和唤醒要通过Object的wait和notify/notifyAllfangAll实现,但后者必须要在同步块里调用,且notify必须要在wait之后调用才行否则会导致线程阻塞。
- public class TestObjWait {
- public static void main(String[] args)throws Exception {
- final Object obj = new Object();
- Thread A = new Thread(new Runnable() {
- @Override
- public void run() {
- int sum = 0;
- for(int i=0;i<10;i++){
- sum+=i;
- }
- try {
- synchronized (obj){
- obj.wait();
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- System.out.println(sum);
- }
- });
- A.start();
- //睡眠一秒钟,保证线程A已经计算完成,阻塞在wait方法
- Thread.sleep(1000);
- synchronized (obj){
- obj.notify();
- }
- }
- }
- public class TestObjWait {
- public static void main(String[] args)throws Exception {
- Thread A = new Thread(new Runnable() {
- @Override
- public void run() {
- int sum = 0;
- for(int i=0;i<10;i++){
- sum+=i;
- }
- LockSupport.park();
- System.out.println(sum);
- }
- });
- A.start();
- //睡眠一秒钟,保证线程A已经计算完成,阻塞在wait方法
- Thread.sleep(1000);
- LockSupport.unpark(A);
- }
- }
LockSupport比Object的wait/notify有两大优势:
①LockSupport不需要在同步代码块里 。所以线程间也不需要维护一个共享的同步对象了,实现了线程间的解耦。
②unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。
3、LockSupport应用
LockSupport在Java工具类中用的很广泛,如并发锁基础AQS、线程池ThreadPoolExecutor等。
浅谈Java并发编程系列(八)—— LockSupport原理剖析
Java并发实现线程阻塞原语LockSupport的更多相关文章
- Java多线程之线程阻塞原语LockSupport的使用
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558597.html 看名字就知道了,LockSupport——提供对加锁机制的支持. 它是提供线程阻塞的原 ...
- Java 并发 中断线程
Java 并发 中断线程 @author ixenos 对Runnable.run()方法的三种处置情况 1.在Runnable.run()方法的中间中断它 2.等待该方法到达对cancel标志的测试 ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- java并发编程 线程基础
java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...
- Java并发1——线程创建、启动、生命周期与线程控制
内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...
- java并发:线程同步机制之Volatile关键字&原子操作Atomic
volatile关键字 volatile是一个特殊的修饰符,只有成员变量才能使用它,与Synchronized及ReentrantLock等提供的互斥相比,Synchronized保证了Synchro ...
- java并发:线程池、饱和策略、定制、扩展
一.序言 当我们需要使用线程的时候,我们可以新建一个线程,然后显式调用线程的start()方法,这样实现起来非常简便,但在某些场景下存在缺陷:如果需要同时执行多个任务(即并发的线程数量很多),频繁地创 ...
- java并发:线程同步机制之Lock
一.初识Lock Lock是一个接口,提供了无条件的.可轮询的.定时的.可中断的锁获取操作,所有加锁和解锁的方法都是显式的,其包路径是:java.util.concurrent.locks.Lock, ...
- Java并发编程:线程间通信wait、notify
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
随机推荐
- 怎样把多个Android Project打包成一个APK
怎样把多个Android Project打包成一个APK(你的项目怎样引用其它项目). 怎样把多个android project 打包成一个apk呢,事实上原理是这种.一个主project引用其它的p ...
- C# 将cookie写入WebBrowser
string cookie = ""; foreach (string c in cookie.Split(';')) { string[] item = c.Split('=') ...
- Thrift安装介绍
一.简介 1.语言库要求 因为thrift支持多语言.所以编译thrift源代码的过程中,会用到该语言的一些类库.如c++的boost.java的jdk等. 那么,在安装thrift过程中,须要对各种 ...
- idea刷新项目、清除项目缓存
点击File -> Invalidate caches ,点击之后在弹出框中点击确认,之后软件就自动重启了
- EC2的维护更新
2014年9月28日 近期几天.我们收到了一些客户关于我们即将进行维护更新的问题.下面是AWS全球Blog网站对这个问题的说明,供客户參照. 我们已经開始通知那些受影响的客户,关于我们即将实施的 ...
- muduo::Connector、TcpClient分析
Connector TcpClient Connector Connector用来发起连接. 在非堵塞网络中,主动发起连接比被动接收连接更为复杂,由于要考虑错误处理,还要考虑重试. 主要难点在于 1. ...
- Jquery 文字模拟输入效果
https://github.com/mattboldt/typed.js/ 挺酷炫的
- poj3040(双向贪心)
Allowance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1540 Accepted: 637 Descript ...
- mysql学习之基础知识
一.什么是数据库 一般而言,数据库(Database)是按照数据结构来组织.存储和管理数据的仓库.我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,使用关系型数据库管理系统(RDB ...
- TEdit的创建与显示过程
-------------------------- 分析TEdit的创建与显示过程 --------------------------TCustomEdit = class(TWinControl ...