关于“LockSupport.park”
跳到导航
跳到搜索
关于
LockSupport (Java Platform SE 8 ):[1] These methods are designed to be used as tools for creating higher-level synchronization utilities, and are not in themselves useful for most concurrency control applications. 这些方法被设计为用于创建更高级别的同步实用程序的工具,而这些方法本身对大多数并发控制应用程序并不有用。 LockSupport 是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞(当然阻塞之后肯定得有唤醒的方法)。
用法
LockSupport.park() 和 LockSupport.unpark() 配合使用,用于“休眠/唤醒当前线程”。
park public static void park() 为了线程调度,禁用当前线程,除非许可(permit)可用。 如果许可可用,则使用该许可,并且该调用立即返回;否则,为线程调度禁用当前线程,并在发生以下三种情况之一以前,使其处于休眠状态: 1、其他某个线程将当前线程作为目标调用 unpark; 2、其他某个线程中断当前线程; 3、该调用不合逻辑地(即毫无理由地)返回。 此方法并不报告是哪个线程导致该方法返回。调用者应该重新检查最先导致线程暂停的条件。调用者还可以确定线程返回时的中断状态。 unpark public static void unpark(Thread thread) 如果给定线程的许可尚不可用,则使其可用。如果线程在上受阻塞,则它将解除其阻塞状态。否则,保证下一次调用不会受阻塞。如果给定线程尚未启动,则无法保证此操作有任何效果。 参数: thread 一要执行 unpark 操作的线程;该参数为表示此操作没有任何效果。
- 示例[2]:
import java.util.concurrent.locks.LockSupport; public class LockSupportTest2 { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{ System.out.println("t1 线程 开始执行"); System.out.println("t1 线程 park() "); LockSupport.park(); System.out.println("t1 线程 继续执行"); System.out.println("t1 线程 当前的 Interrupt 状态:"+Thread.currentThread().isInterrupted()); }); t1.start(); Thread.sleep(1000L); // unpark t1线程 LockSupport.unpark(t1); } }
tl 线程 开始执行 tl 线程 park() tl 线程 继续执行 tl 线程 当前的 Interrupt 状态:false
LockSupport.park(Object blocker) 和 LockSupport.getBlocker(Thread thread) 配合使用,可以进行自定义数据传输。
- blocker 为线程 thread 中定义的需要传输的数据类型。
- 示例[2]:
import java.util.HashMap; import java.util.concurrent.locks.LockSupport; public class LockSupportTest { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{ System.out.println("t1 线程 开始执行"); System.out.println("t1 线程 parkNanos() "); HashMap blocker = new HashMap(); blocker.put("reason","测试LockSupport的park的blocker"); blocker.put("code","1000"); LockSupport.parkNanos(blocker, 2000*1000*2000L); System.out.println("t1 线程 继续执行"); System.out.println("t1 线程 当前的 Interrupt 状态:" + Thread.currentThread().isInterrupted()); }); t1.start(); Thread.sleep(1000L); Object blocker = LockSupport.getBlocker(t1); System.out.println("t1 线程 的 blocker:" + blocker); Thread.sleep(1000*100L); } }
tl 线程 开始执行 tl 线程 parkNanos() tl 线程 的 blocker: {reason=测试LockSupport的park的blocker, code=1000} tl 线程 继续执行 tl 线程当前的 Interrupt 状态:false
区别
LockSupport.park 与 Thread.sleep、Object.wait 语义类似,但有如下区别:
- LockSupport.park 方法会进入 WAITING 状态,而 LockSupport.parkNanos 会进入 TIMED_WAITING 状态。
- 【Thread.sleep 进入 TIMED_WAITING 状态; Object.wait 进入 WAITING 或 TIMED_WAITING 状态】
- LockSupport.park 不依赖 monitor 锁(与 synchronized 无关),所以不涉及锁的释放与否。
- 【Thread.sleep 也不涉及锁的释放; 但 Object.wait 将会释放锁】
- LockSupport.park 不会抛出受检查异常,不会吞掉 interrupt 标志位。
- 【Thread.sleep 与 Object.wait 线程被打断的时候会抛出异常,而且 catch 代码块中得到的 interrupt 状态永远是 false】
- 可以通过 Interrupt 的状态来“判断线程是不是被 interrupt 的(“中断标识”为“true”),还是被 unpark 或者到达指定休眠时间(“中断标识”为“false”)”。
- LockSupport.park 和 LockSupport.unpark 的使用不会出现死锁的情况。