看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里,只有两个函数:

  1. public native void unpark(Thread jthread);
  2. 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 a SecurityException to be thrown.

    If this thread is blocked in an invocation of the wait()wait(long), or wait(long, int) methods of the Object class, or of the join()join(long)join(long, int)sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. (这是正确而且必须的行为,否则就有可能会导致共享变量处于不一致的状态)

    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's wakeup 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/.

最新文章

  1. 在Linux系统下运行微信Web开发者工具
  2. 关于从Activity A跳转到Activity B ,其中Activity A中有一个VideoView,Activity B中有一个MediaPlayer。
  3. 库AFNetworking的使用
  4. thinkphp 模型、控制器、视图
  5. Linux下man手册使用
  6. ehcache基本使用
  7. javascript_获取浏览器属性
  8. 【Android测试】【随笔】与 “58同城” 测试开发交流
  9. 【转】div弹出窗口的制作
  10. Eclipse常用功能
  11. vi/vim 键盘
  12. 英语学习笔记---01---新概念第一册---Lesson 1 Excuse me!
  13. 【记录】Xmind8 Pro 激活
  14. Linux端口转发-rinted工具部署、配置、使用
  15. idea创建maven SSM项目
  16. 【SQLite】可视化工具SQLite studio
  17. python 进程创建和共享内容的方法
  18. iOS GameCenter 接入
  19. 占位符 %s
  20. 如何把C盘里的文件默认位置更改到D盘指定目录?

热门文章

  1. 虚拟IP技术
  2. Centos6.5建立本地YUM源
  3. python shutil.copytree 解决目标目录存在的情况
  4. 44.JS--hover事件防重复效果
  5. vue中使用echarts来绘制世界地图和中国地图
  6. laravel 前后端分离 token
  7. C# Mongo Client 2.4.2创建索引
  8. MYSQLi数据访问批量删除
  9. Mybatis分页插件pagehelper的使用
  10. springboot maven项目,为什么build成功,build path也没错误,project--&gt;clean 也没用,项目上面还是有个红x呢?