java中线程的停止以及LockSupport工具类
看jstack输出的时候,可以发现很多状态都是TIMED_WAITING(parking),如下所示:
"http-bio-8080-exec-16" #70 daemon prio=5 os_prio=0 tid=0x00007f6088027800 nid=0x3a1f waiting on condition [0x00007f60fcd03000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006cb8d7500> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:86)
at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:32)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
关于LockSupport,查看相关资料,可知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时,它发现已经有“许可”了,那么它会马上再继续运行。
在JDK 5里面,是用wait/notify/notifyAll来同步的,它没有LockSupport那样的容忍性,所以JDK7 JUC之后几乎都是采用park与unpark实现。 至于其提供的额外监视器参数,主要是jstack排查方便。
我们知道,线程的shutdown从标准的角度来说,就是给线程发送一个interupt,线程自行决定是否响应,具体是否相应的标准如下:
interrupt
public void interrupt()
Interrupts this thread.Unless the current thread is interrupting itself, which is always permitted, the
checkAccess
method of this thread is invoked, which may cause aSecurityException
to be thrown.If this thread is blocked in an invocation of the
wait()
,wait(long)
, orwait(long, int)
methods of theObject
class, or of thejoin()
,join(long)
,join(long, int)
,sleep(long)
, orsleep(long, int)
, methods of this class, then its interrupt status will be cleared and it will receive anInterruptedException
. (这是正确而且必须的行为,否则就有可能会导致共享变量处于不一致的状态)If this thread is blocked in an I/O operation upon an
interruptible channel
then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a
ClosedByInterruptException
.If this thread is blocked in a
Selector
then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector'swakeup
method were invoked.If none of the previous conditions hold then this thread's interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
- Throws:
SecurityException
- if the current thread cannot modify this thread
所以,对于那些无法响应中断的线程中的逻辑,我们需要根据isInterupted来判断决定是否终止自己,不过不可否认的是,现实中有很多的应用并没有这么做。关于对中断的处理方式,可参考Java theory and practice: Dealing with InterruptedException 。
最后看一下,对于那些使用park阻塞的线程,是否支持Interrupt,看javadoc是支持的,如下:
关于java中断,讲得比较好的帖子是:
http://agapple.iteye.com/blog/970055
关于LockSupport,可参见:
http://blog.csdn.net/hengyunabc/article/details/28126139
以及java doc参考https://docs.oracle.com/javase/7/docs/api/.
java中线程的停止以及LockSupport工具类的更多相关文章
- java中模拟http(https)请求的工具类
在java中,特别是java web中,我们经常需要碰到的一个场景是我们需要从服务端去发送http请求,获取到数据,而不是直接从浏览器输入请求网址获得相应.比如我们想访问微信接口,获取其返回信息. 在 ...
- java中map和对象互转工具类的实现示例
在项目开发中,经常碰到map转实体对象或者对象转map的场景,工作中,很多时候我们可能比较喜欢使用第三方jar包的API对他们进行转化,而且用起来也还算方便,比如像fastJson就可以轻松实现map ...
- Java并发包源码学习系列:挂起与唤醒线程LockSupport工具类
目录 LockSupport概述 park与unpark相关方法 中断演示 blocker的作用 测试无blocker 测试带blocker JDK提供的demo 总结 参考阅读 系列传送门: Jav ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor
原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...
- Java多线程并发03——在Java中线程是如何调度的
在前两篇文章中,我们已经了解了关于线程的创建与常用方法等相关知识.接下来就来了解下,当你运行线程时,线程是如何调度的.关注我的公众号「Java面典」了解更多 Java 相关知识点. 多任务系统往往需要 ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- java中线程机制
java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...
- Java中线程的使用 (2)-多线程、线程优先级、线程睡眠、让步、阻塞
Java中线程的使用 (2)-多线程.线程优先级.线程睡眠.让步.阻塞 (一)多线程使用方法 说明:创建每个新的线程,一定要记得启动每个新的线程(调用.start()方法) class Xc3 ext ...
随机推荐
- 18-Python3 迭代器与生成器
2018-11-22 16:14:01 print('迭代器********************************************************************** ...
- SEO--简介
SEO:搜索引擎优化 不需付费 SEM:搜索引擎营销 需要付费 IP:每个家庭每个公司应该是同个IP PV:网站刷新搜索总量 UV:独立用户访客
- python list成员函数extend与append的区别
extend 原文解释,是以list中元素形式加入到列表中 extend list by appending elements from the iterable append(obj) 是将整个ob ...
- cocos2dx (关于斗地主人物偏移位置)
就是说不管是谁登陆游戏,你的人物信息资料始终在平板电脑的屏幕正下方(位置坐标需要自己设定,我设置定的是0号位() char LandLordsScene::getUIPosition(char pos ...
- mybatis--parametertype的参数传递
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
- HashMap的底层实现原理
HashMap的底层实现原理1,属性static final int MAX_CAPACITY = 1 << 30;//1073741824(十进制)0100000000000000000 ...
- Ant打包可运行的Jar包(加入第三方jar包)
本章介绍使用ant打包可运行的Jar包. 打包jar包最大的问题在于如何加入第三方jar包使得jar文件可以直接运行.以下用一个实例程序进行说明. 程序结构: 关键代码: package com.al ...
- linux下postgresql的连接数配置
1.查询当前连接数: select count(*) from pg_stat_activity; 2.查询最大连接数 show max_connections; 3.修改最大连接数 SHOW con ...
- HDU 3461 Code Lock(并查集+二分求幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3461 A lock you use has a code system to be opened in ...
- 文字列大好きいろはちゃんイージー / Iroha Loves Strings (ABC Edition) (优先队列)
题目链接:http://abc042.contest.atcoder.jp/tasks/abc042_b Time limit : 2sec / Memory limit : 256MB Score ...