LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语。
LockSupport实际上是调用了Unsafe类里的函数,归结到Unsafe里,只有两个函数:
public native void unpark(Thread jthread);
public native void park(boolean isAbsolute, long time);
isAbsolute参数是指明时间是绝对的,还是相对的。
仅仅两个简单的接口,就为上层提供了强大的同步原语。
先来解析下两个函数是做什么的。
unpark函数为线程提供“许可(permit)”,线程调用park函数则等待“许可”。
这个有点像信号量,但是这个“许可”是不能叠加的,“许可”是一次性的。
比如线程B连续调用了三次unpark函数,当线程A调用park函数就使用掉这个“许可”,如果线程A再次调用park,则进入等待状态。
注意,unpark函数可以先于park调用。比如线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行。
实际上,park函数即使没有“许可”,有时也会无理由地返回,这点等下再解析。
park和unpark的灵活之处
上面已经提到,unpark函数可以先于park调用,这个正是它们的灵活之处。
一个线程它有可能在别的线程unPark之前,或者之后,或者同时调用了park,那么因为park的特性,它可以不用担心自己的park的时序问题,否则,如果park必须要在unpark之前,那么给编程带来很大的麻烦!!
考虑一下,两个线程同步,要如何处理?
在Java5里是用wait/notify/notifyAll来同步的。wait/notify机制有个很蛋疼的地方是,比如线程B要用notify通知线程A,那么线程B要确保线程A已经在wait调用上等待了,否则线程A可能永远都在等待。编程的时候就会很蛋疼。
另外,是调用notify,还是notifyAll?
notify只会唤醒一个线程,如果错误地有两个线程在同一个对象上wait等待,那么又悲剧了。为了安全起见,貌似只能调用notifyAll了。
park/unpark模型真正解耦了线程之间的同步,线程之间不再需要一个Object或者其它变量来存储状态,不再需要关心对方的状态。
举例:
park: 直接阻塞
public static void test2(){
LockSupport.park();
System.out.println("block.");
}
unpark&park
public static void test1(){
LockSupport.unpark(Thread.currentThread());
System.out.println(LockSupport.getBlocker(Thread.currentThread()));;
LockSupport.park();
System.out.println("block.");
}
unpark&park&park (unpark只能许可一次)
public static void test1(){
LockSupport.unpark(Thread.currentThread());
System.out.println(LockSupport.getBlocker(Thread.currentThread()));;
LockSupport.park();
LockSupport.park();
System.out.println("block.");
}
park & unpark
public static void test4() throws Exception
{
Thread t = new Thread(new Runnable()
{
private int count = 0;
@Override
public void run()
{
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);
// 中断线程
LockSupport.unpark(t);
System.out.println("main over");
}
park&interrupt:
public static void test3() throws Exception
{
Thread t = new Thread(new Runnable()
{
private int count = 0;
@Override
public void run()
{
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");
}
分享到:
相关推荐
LockSupport是JDK1.6中在java.util.concurrent中的子包locks中引入的一个比较底层的工具类,用来创建锁和其他同步工具类的基本线程阻塞原语。java锁和同步器框架的核心 AQS: AbstractQueuedSynchronizer,就是通过...
在Java多线程中,当需要阻塞或者唤醒一个线程时,都会使用LockSupport工具类来完成相应的工作。LockSupport定义了一组公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能,而LockSupport也因此成为了构建同步...
Java 多线程与并发(9_26)-JUC锁_ LockSupport详解
主要给大家介绍了关于Java并发编程学习之Unsafe类与LockSupport类源码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧
LockSupport类提供了park()和unpark()两个方法来实现线程的阻塞和唤醒,下面我们就来详解Java多线程编程中LockSupport类的线程阻塞用法:
本文将详细介绍java线程阻塞中断和LockSupport的使用,需要了解更多的朋友可以参考下
主要为大家详细介绍了Java concurrency之LockSupport的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
AQS 原理 ...LockSupport.park() 完成,而 LockSupport.park() 则调用 sun.misc.Unsafe.park()本地方法,再进一步,HotSpot 在 Linux 中中通过调用 pthread_mutex_lock 函数把线程交给系统内核进行阻塞。
Thread.sleep()和LockSupport.park()的区别 Object.wait()和LockSupport.park()的区别 线程和线程池 线程池的五种状态 线程池类型 线程池原理 线程池构造函数参数; 线程池的4种拒绝策略; 线程池中任务结束后会不会...
一、理论基础 1.1为什么需要多线程 1.2不安全示例 1.3并发问题的根源 1.4JMM 1.5线程安全的分类 1.6线程安全的方法 二、线程基础 2.1状态 2.2使用方式 2.3基础机制 ...十一、JUC锁: LockSupport详解
一. 1.创建线程: (1)在创建线程时,传入Runnable接口的实现类,重写run方法指定执行任务 (2)使用FutureTask(实现Runnable接口)来指定任务,可以通过get方法来获得执行...(5)Park:LockSupport的静态方法,在调用时会
13.LockSupport工具 14.并发容器之ConcurrentHashMap(JDK 1.8版本) 15.并发容器之ConcurrentLinkedQueue 16.并发容器之CopyOnWriteArrayList 17.并发容器之ThreadLocal 18.一篇文章,从源码深入详解ThreadLocal内存...
测试LockSupport,LockSupport基于一个“许可”的概念实现了线程的阻塞与释放,该测试demo就是为了使这个“许可”的概念更加的清晰
LockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习demoLockSupport学习...
java并发,主要用于初学者学习,主要案列,Thread.join,ThreadLocal,Lock接口,LockSupport,Condition接口,ConcurrentHashMap的实现原理与使用 Fork/Join 框架,CountDownLatch,CyclicBarrier,Semaphore,...
Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...
干扰翻译 Disruptor原始代码分解析出(超详细注释),版本3.4.2,方便... 增加LockSupport.parkNanos的默认睡眠时间,以防止忙碌旋转。 3.3.8 放回皮带和支架WaitStrategy发出信号。 3.3.7 将批次大小添加到BatchStar
我们经常在JUC包下的ConcurrentHashMap、Atomic开头的原子操作类、AQS以及LockSupport里面看到Unsafe类的身影,这个Unsafe类究竟是干什么的,本文可以带着读者一探究竟。 Java和C++、C语言的一个重要区别,就是Java...