09-java线程生命周期

一、java线程生命周期

 

 处于休眠状态(blocked、waiting、timed_waiting)的线程,没有CPU的使用权。

二、Runnable状态和休眠状态之间的状态转换

 

 三、Runnable状态到Terminated状态

线程执行完run()方法后,会自动切换到terminated状态;

线程执行过程中,有时我们需要强制终止线程的执行,比如访问一个很慢的网络。强制终止线程有两种方式:stop()和interrupt()

1、stop(),已不建议使用。并且如果线程持有ReentrantLock锁,如果使用stop()终止线程,线程并不会自动调用reentrantLock的unlock()方法去释放锁,会使得该线程立即被杀死,其他线程永远无法获得这个锁。

2、interrupt(),中断线程的正确姿势。使用这个方法,仅仅是通知这个线程,这个线程有机会做一些后续的操作,也可以无视这个通知。

思考:以下代码本意是当前线程被中断之后,跳出while(true)循环,但是其中有问题。

 1 Thread th = Thread.currentThread();
 2 while(true) {
 3   if(th.isInterrupted()) {
 4     break;
 5   }
 6   // 省略业务代码无数
 7   try {
 8     Thread.sleep(100);
 9   }catch (InterruptedException e){
10     e.printStackTrace();
11   }
12 }
View Code

以上代码可能出现无限循环,线程在sleep期间被打断了,抛出一个InterruptedException异常,try catch捕捉此异常,应该重置一下中断标示,因为在抛出InterruptedException后会清除中断标志(代表可以接收下一个中断信号了)!
Thread th = Thread.currentThread();
while(true) {
  if(th.isInterrupted()) {
    break;
  }
  // 省略业务代码无数
  try {
    Thread.sleep(100);
  }catch (InterruptedException e){
    Thread.currentThread().interrupt();
    e.printStackTrace();
  }
}

四、诊断并发问题的一个重要工具---Java VisualVM

可以通过 jstack 命令或者Java VisualVM这个可视化工具将 JVM 所有的线程栈信息导出来,完整的线程栈信息不仅包括线程的当前状态、调用栈,还包括了锁的信息。例如,我曾经写过一个死锁的程序,导出的线程栈明确告诉我发生了死锁,并且将死锁线程的调用栈信息清晰地显示出来了(如下图)。导出线程栈,分析线程状态是诊断并发问题的一个重要工具。

java Visual VM在java 6之后自带工具,无须独立安装。在安装目录bin下,打开后直接使用。

 

posted @ 2019-10-21 15:16  45°仰望星空  阅读(118)  评论(0编辑  收藏  举报