java 线程resume_Java多线程——过期的suspend()挂起、resume()继续执行线程

简述

LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞。

和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执行的情况。

和 Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出 InterruptedException 异常。

LockSupport 的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos()、parkUntil()等方法。它们实现了一个限时等待,如下图所示:

fce19e9233520833ba9d1dac4836a890.png

实例

1 import java.util.concurrent.locks.LockSupport;

2 /**

3 * Created by zhengbinMac on 2017/3/5.

4 */

5 public class SuspendResumeTest {

6 public static Object object = new Object();

7 static TestThread t1 = new TestThread("线程1");

8 static TestThread t2 = new TestThread("线程2");

9 public static class TestThread extends Thread{

10 public TestThread(String name) {

11 super.setName(name);

12 }

13 @Override

14 public void run() {

15 synchronized (object) {

16 System.out.println(getName()+" 占用。。");

17 // Thread.currentThread().suspend();

18 LockSupport.park();

19 System.out.println(Thread.currentThread().getName()+" 执行结束!");

20 }

21 }

22 }

23 public static void main(String[] args) throws InterruptedException {

24 t1.start();

25 Thread.sleep(200);

26 t2.start();

27 // t1.resume();

28 LockSupport.unpark(t1);

29 LockSupport.unpark(t2);

30 // t2.resume();

31 t1.join();

32 t2.join();

33 }

34 }

代码只是对Java多线程——过期的suspend()挂起、resume()继续执行线程中实例稍作修改,将 suspend()和 resume()改为 park()与 unpark()。

修改后,同样的问题:我们依然无法保证 unpark()方法发生在 park()之后,但是多次执行代码,发现始终都可以正常结束,不会因为两方法的顺序导致线程永久性挂起。

这是因为,其使用类似信号量的机制。

它为每个线程准备了一个许可,如果许可可用,那么 park()方法立即返回,并消费这个许可(将许可变为不可用);如果许可不可用,则阻塞。

而 unpark()方法,则是使一个许可变为可用。

上述特点使得:即使 unpark()操作发生在 park()之前,它也可以使下一次得 park()操作立即返回。这是上述实例代码顺利结束的原因。

同时,park()挂起的线程不会像 suspend()那样线程状态为 RUNNABLE,park()会明确给出 WAITING 状态,并标注由 park()引起,如下图所示:

5c31e1d664cf565f3bec8ab491cacb8e.png

这个标注,使得分析问题时更加方便,可以使用 park(Object)方法,为当前线程设置一个阻塞对象,这个阻塞对象会出现在线程 Dump 中。

将实例中 18 行改为:

LockSupport.park(this);

jstack 输出为:

bfbda685b402b7cf8d4ee3efa2d40ab4.png

参考资料

[1] 实战Java高并发程序设计, 3.1.7 - 线程阻塞工具类:LockSupport

[2] Java并发编程的艺术, 5.5 - LockSupport工具

来源:https://www.cnblogs.com/zhengbin/p/6506166.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值