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");
}
分享到:
相关推荐
Java中的LockSupport是一个底层工具类,它在JDK 1.6版本中被引入到`java.util.concurrent.locks`包中,主要用于构建锁和其他同步工具类。LockSupport的核心功能是提供线程阻塞和唤醒的原语,这些功能在Java的并发...
LockSupport是Java中用于多线程同步的一个工具类,它提供了一组基础的线程阻塞和解除阻塞的方法。这个类位于java.util.concurrent.locks包下,是实现并发编程中AQS(AbstractQueuedSynchronizer)框架的重要基础之一...
在Java并发编程中,LockSupport和Unsafe是两个关键的工具类,它们提供了底层的线程控制功能,使得开发者能够深入地管理和控制线程的行为。LockSupport是Java并发库中的一个核心工具类,它提供了线程的阻塞和唤醒功能...
《深入解析Java并发编程:Unsafe类与LockSupport类源码剖析》 在Java并发编程领域,Unsafe类和LockSupport类是两个重要的底层工具类,它们提供了低级别的内存操作和线程控制,使得开发者能够实现高效的并发算法和...
在Java多线程编程中,LockSupport类是一个重要的工具,它提供了一种低级别的线程阻塞和唤醒机制。LockSupport并不像synchronized或java.util.concurrent.locks包中的Lock接口那样提供锁的完整功能,但它提供了两个...
Java concurrency之LockSupport Java concurrency之LockSupport是Java并发编程中的一种基础设施,用于创建锁和其他同步类的基本线程阻塞原语。LockSupport提供了一组函数来实现线程之间的同步和通信,使得开发者...
`Thread.interrupt()` 方法是用于向线程发送中断请求,而`LockSupport` 是Java 5引入的一个低级别的线程同步工具,提供了比`synchronized` 和 `java.util.concurrent.locks` 包更细粒度的控制。下面我们将详细讨论这...
LockSupport是Java并发编程中的一个重要工具类,位于`java.util.concurrent.locks`包下,它提供了线程阻塞和唤醒的底层支持。在Java多线程编程中,LockSupport主要用于构建锁和其他同步机制,比如ReentrantLock和...
ScheduledThreadPoolExecutor 使用DelayedWorkQueue来实现延迟任务的执行,并使用LockSupport.parkNanos 方法来阻塞当前线程,直到队列中有任务可用。 在 Java 中,ScheduledThreadPoolExecutor 是一个高效的线程池...
在Android开发中,`LockSupport` 是一个非常重要的工具类,它属于并发处理包 `java.util.concurrent.locks`。这个类提供了低级别的线程阻塞和唤醒机制,可以帮助开发者实现复杂的线程同步策略。在标题和描述中提到的...
【描述】提到的重点在于JUC(Java并发包)中的可重入锁概念,以及与之相关的锁机制,如LockSupport工具类的使用。此外,还提到了LockSupport如何实现线程的阻塞和唤醒,以及AbstractQueuedSynchronizer (AQS) 在锁和...
本文将基于JDK源码解析Java领域中的并发锁,探讨AQS基础同步器、LockSupport、Condition接口、Lock接口、ReadWriteLock接口以及自定义API操作的设计与实现。 一、AQS(AbstractQueuedSynchronizer)基础同步器的...
【部分内容】:章节内容主要涵盖Java基础,包括字符串常量池的行为,以及JUC(Java并发工具包)中的可重入锁原理和LockSupport的线程阻塞与唤醒机制。 1. **Java基础 - 字符串常量池** - 在JDK7及以上版本,字符串...
其中线程休眠中重点学习了sleep()方法、LockSupport类下的park()和unpark()方法、以及sleep()方法和park()方法的区别,此外需要注意的是,Interrupt()方法能够使调用特定方法而处于阻塞状态的线程恢复运行,但通常不...
这些操作在Java并发库的`LockSupport`类中被封装,`LockSupport.park()`和`LockSupport.unpark(Thread)`都是基于`Unsafe`实现的。这种机制在实现自定义同步原语时非常有用。 4. CAS(Compare and Swap)操作: CAS...
以上介绍了 Java 并发编程中几个重要的概念和技术,包括 `ReentrantLock`、`Condition`、`Semaphore`、`ReadWriteLock`、`CountDownLatch`、`CyclicBarrier` 和 `LockSupport`。这些技术为我们提供了丰富的并发控制...
JUC包在Java 5引入,提供了更为丰富的锁机制和高级同步工具,如Lock接口、ReadWriteLock接口、LockSupport阻塞原语、Condition条件以及相关的抽象类和实现类。 - Lock接口:Lock提供了比`synchronized`更细粒度的...
在Java中,`java.util.concurrent.locks.LockSupport.parkNanos()`和`LockSupport.parkUntil()`方法可以用来实现自旋锁。`ReentrantLock`内部就使用了自旋锁策略,它会根据当前系统环境和锁的状态决定是否进行自旋。...