挂起(suspend)与线程阻塞工具类LockSupport

一般来说是不推荐使用suspend去挂起线程的,因为suspend在导致线程暂停的同时,并不会去释放任何锁资源. 如果其他任何线程想要访问被它暂用的锁时,都会被牵连,导致无法正常继续运行. 直到对应的线程上进行了resume操作.

并且,如果resume操作意外的在suspend前执行了,那么被挂起的线程可能很难有机会被继续执行,更严重的是:它所占用的锁不会被释放,因此可能会导致整个系统工作不正常,而且,对于被挂起的线程,从它的线程状态上看,居然还是Runnable

/**
* @author luozhiyun on 2018/6/24.
*/
public class BadSuspend { public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread{
public ChangeObjectThread(String name) {
super.setName(name);
} @Override
public void run() {
synchronized (u) {
System.out.println("in " + getName());
Thread.currentThread().suspend();
}
}
} public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(100);
t2.start();
t1.resume();
t2.resume();
t1.join();
t2.join();
}
}

执行后我们可能会得到以下输出:

in t1
in t2

这表明两个线程先后进入了临界区,但是程序不会退出

线程阻塞类:LockSupport

它可以在线程内任意位置让线程阻塞. 和Thread.suspend()相比,它弥补了由于resume()在前发生,导致线程无法继续执行的情况.和Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出InterruptedException

LockSupport的静态方法park()可以阻塞当前线程,类似的还有parkNanos() / parkUntil()等方法.它们实现了一个限时的等待

/**
* @author luozhiyun on 2018/6/24.
*/
public class LockSupportDemo { public static Object u = new Object();
static ChangeObjectThread t1 = new ChangeObjectThread("t1");
static ChangeObjectThread t2 = new ChangeObjectThread("t2");
public static class ChangeObjectThread extends Thread{
public ChangeObjectThread(String name) {
super.setName(name);
} @Override
public void run() {
synchronized (u) {
System.out.println("in " + getName());
LockSupport.park(this);
}
}
} public static void main(String[] args) throws InterruptedException {
t1.start();
Thread.sleep(100);
t2.start();
LockSupport.unpark(t1);
LockSupport.unpark(t2);
t1.join();
t2.join();
}
}

这段代码至始至终都可以正常的结束,不会因为park()方法而导致线程永久性的挂起

这事因为LockSupport类使用类似信号量的机制.它为每一个线程准备了一个许可,如果许可可用,那么park()函数会立即返回,并且消费这个许可(也就是将许可变成不可用).如果许可不可用,就会阻塞.而unpark()则使得一个许可变为可用(但是和信号量不同的是,许可不能累加,你不可能拥有超过一个许可,它永远只有一个)

这个特点使得:即使unpark()操作发生在park()之前,它也可以使下一次的park()操作立即返回

同时,处于park()挂起状态的线程不会像suspend()那样还给出一个令人费解的Runnable的状态.它会非常明确地给出一个WAITING状态,甚至还会是标注是park()引起的

挂起(suspend)与线程阻塞工具类LockSupport的更多相关文章

  1. Java多线程系列——线程阻塞工具类LockSupport

    简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执 ...

  2. 线程阻塞工具类:LockSupport(读书笔记)

     他可以在线程任意位置让线程阻塞, LockSupport的静态方法park()可以阻塞当前线程,类似的还有parkNanos() ParkUntil()等,他们实现了一个限时等待 public cl ...

  3. AQS 框架之 LockSupport 线程阻塞工具类

    ■ 前言 并发包一直是 JDK 里面比较难理解的,同时也是很精美的语言,膜拜下 Doug Li 大神.作者不敢长篇大论,只求循序渐进地把并发包通过理论和实战 (代码) 的方式介绍给大家. 其实做每一件 ...

  4. 3.1.7 线程阻塞工具类:LockSupport

    package 第三章.线程阻塞工具LockSupport; import java.util.concurrent.locks.LockSupport; /** * Created by zzq o ...

  5. 26.LockSupport线程阻塞工具

    import java.util.concurrent.locks.LockSupport; /** * 线程阻塞工具类:LockSupport * 可以在线程内任意位置让线程阻塞 */ public ...

  6. java线程并发工具类CyclicBarrier、CountDownLatch及Semaphore

    一.CyclicBarrier   (原文链接:http://www.studyshare.cn/blog-front/blog/index ) 1.定义 CyclicBarrier是线程并发工具类之 ...

  7. 线程并发工具类之CountDownLatch的使用及原理分析

    原文链接:http://www.studyshare.cn/blog/details/1149/1 java开发工具下载地址及安装教程大全,点这里.更多技术文章,在这里. 一.定义 CountDown ...

  8. Java核心知识点学习----线程同步工具类,CyclicBarrier学习

    线程同步工具类,CyclicBarrier日常开发较少涉及,这里只举一个例子,以做备注.N个人一块出去玩,相约去两个地方,CyclicBarrier的主要作用是等待所有人都汇合了,才往下一站出发. 1 ...

  9. java线程并发工具类

    本次内容主要讲Fork-Join.CountDownLatch.CyclicBarrier以及Callable.Future和FutureTask,最后再手写一个自己的FutureTask,绝对干货满 ...

随机推荐

  1. ASP.NET Core Web API中使用Swagger

    本节导航 Swagger介绍 在ASP.NET CORE 中的使用swagger   在软件开发中,管理和测试API是一件重要而富有挑战性的工作.在我之前的文章<研发团队,请管好你的API文档& ...

  2. Jenkins+svn+ftp自动化发布asp.net项目

    今天将自己所掌握的(Jenkins+svn+ftp自动化发布asp.net项目)知识分享给大家,希望能帮组到大家: (1)先下载Jenkins并安装: (2)安装.Net所需要的插件: (3)配置插件 ...

  3. spark 源码分析之十二 -- Spark内置RPC机制剖析之八Spark RPC总结

    在spark 源码分析之五 -- Spark内置RPC机制剖析之一创建NettyRpcEnv中,剖析了NettyRpcEnv的创建过程. Dispatcher.NettyStreamManager.T ...

  4. 2019.6.5 NOIP2014 day2 t2 寻找道路

    我竟然一个人敲了NOIP提高组的t2? 题目描述 在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 路径上的所有点的出边所指向的点都直 ...

  5. aspnetcore 实现简单的伪静态化

    aspnetcore 实现简单的伪静态化 Intro 在我的活动室预约项目中,有一个公告模块,类似于新闻发布,个人感觉像新闻这种网页基本就是发布的时候编辑一次之后就再也不会改了,最适合静态化了, 静态 ...

  6. git中常用的操作命令有哪些?常用操作命令归纳

    git中常用的操作命令有哪些?本篇文章就给到大家归纳了一些git中常用操作命令.有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. git开始 全局配置:配置用户名和e-mail地址 1 ...

  7. django基础知识之Ajax:

    使用Ajax 使用视图通过上下文向模板中传递数据,需要先加载完成模板的静态页面,再执行模型代码,生成最张的html,返回给浏览器,这个过程将页面与数据集成到了一起,扩展性差 改进方案:通过ajax的方 ...

  8. 数字IC前后端设计中的时序收敛(五)--Max Transition违反的修复方法

    本文转自:自己的微信公众号<数字集成电路设计及EDA教程> 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具的教程. 考虑到微信公众 ...

  9. kuangbin专题 专题一 简单搜索 Fire! UVA - 11624

    题目链接:https://vjudge.net/problem/UVA-11624 题意:一个迷宫,可能有一个或者多个地方着火了,每过1个时间消耗,火会向四周蔓延,问Joe能不能逃出迷宫,只要走出迷宫 ...

  10. 用SpringBoot+MySql+JPA实现对数据库的增删改查和分页

    使用SpringBoot+Mysql+JPA实现对数据库的增删改查和分页      JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述 ...