在多线程中,线程在不同的情况下会有不同的状态,了解线程的状态可以帮助我们更好的掌握多线程。
线程状态简介
在JDK8中,Thread一共有六种状态,它们被定义在一个枚举里,我们根据源码来大概看一下不同的状态的定义。
-
NEW (初始状态)
-
RUNNABLE(运行状态)
-
BLOCKED(阻塞状态)
-
WAITING(等待状态)
-
TIMED_WAITING(超时等待状态)
-
TERMINATED(终止状态)
对线程状态的理解
声明,下述均为本人个人见解,如有错误,还望批评指正(喷的时候轻一点,谢谢)
我们现在已经知道了线程有六大状态(初始状态,运行状态,阻塞状态,等待状态,超时等状态,终止状态),现在让我们根据代码来理解一下这几种状态。
初始状态就是线程刚刚被new出来的时候,是还没有调用strat()方法的状态。这也能解释为什么start()方法不能调用多次而run()可以,因为run()是执行线程的任务列表,而start()是改变线程的状态,二者本质上就不同。
1
2
3
4
5
6
7
8
9
10
11
12public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public void run() { } }); System.out.println(thread.getState()); thread.start(); System.out.println(thread.getState()); }
运行状态,其实应该是可运行状态,它代表当前线程可以运行或者正在运行。其实RUNNABLE状态可以细分为两个状态,或者说它代表了两个状态。这两个状态分别是RUNNING(正在运行状态),与READY(就绪状态)。很明显,RUNNING代表线程正在运行时的状态,而READY代表线程处于随时可以运行的状态。
阻塞状态,就是线程因为某种原因要暂时放弃CUP的执行权,停止运行,直到该线程进入就绪状态后,才有机会运行。等待状态和超时间等待状态其实也可以看作一种阻塞状态,只是阻塞的原因不同。
线程阻塞的部分原因 :
- 睡眠状态
当线程调用sleep()方法时,线程就处于睡眠状态。该状态下线程不会释放锁对象。等线程睡眠时间一过,就会进入就绪状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public static void main(String[] args) throws InterruptedException { Object sy = new Object(); Thread t1 = new Thread(()->{ synchronized (sy){ try { Thread.sleep(1000);//sleep时并不会释放锁资源 } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread t2 = new Thread(()->{ synchronized (sy){ System.out.println("t2执行了"); } }); t1.start(); t2.start(); Thread.sleep(100);//防止Main线程执行过快 System.out.println("t2的状态是"+t2.getState()); }
- 等待状态
一个线程正在运行,如果调用了wait()方法,此时该线程会进入阻塞状态,并释放锁资源。进入这种状态不需要设置睡眠时间,但需要执行notify()或者notifyAll()对其进行唤醒,自己是不会主动醒来的。调用wait()属于无时间限制的WAITING状态。
- 礼让状态
一个线程运行时如果执行yield方法,则其会将执行权让给其它线程,自己进入阻塞状态,但是不会释放锁。故该线程随时可能会又被分配到执行权。
- 自闭状态
一个正在运行的线程内部调用了join()方法,此时该线程会进入阻塞状态,直到调用join()方法的线程运行结束,该线程才恢复就绪状态。这种阻塞属于无时间限制的WAITING状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{ try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } },"t1"); Thread t2 = new Thread(()->{ try { t1.join();//调用join方法 } catch (InterruptedException e) { e.printStackTrace(); } },"t2"); t1.start(); t2.start(); Thread.sleep(1000);//避免主线程太快结束而看不到结果 System.out.println(t2.getName()+"处于"+t2.getState()+"状态"); }
线程阻塞也可能时争夺锁资源失败后进入阻塞状态,这比较常见。
最后,附上一副关于线程状态的图。
这篇博客是偏向笔记类的博客,日后可能会修改,
都看到这了,不考虑点个赞评个论吗???
最后
以上就是陶醉乐曲最近收集整理的关于多线程--线程的六种状态线程状态简介对线程状态的理解的全部内容,更多相关多线程--线程内容请搜索靠谱客的其他文章。
发表评论 取消回复