线程状态
1.初始状态(NEW)
- 实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态
2.1就绪状态(RUNNABLE之READY)
- 1.继续状态指示说你有资格运行,调度程序没有挑选到你,你就永远都是就绪状态
- 2.调用线程的start()方法,此线程进入就绪状态
- 3.当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将今日就绪状态
- 4.当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
- 5.锁池里的线程拿到对象锁后,进入就绪状态
2.2.运行中状态(RUNNABLE值RUNNING)
- 线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进去运行状态的唯一的一种方式
3.阻塞状态(BLOCKED)
- 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
- 进入阻塞:sleep,wait,join,IOd的read,write
4.等待(WAITING)
- 处于这种状态的线程不会被分配CPU执行时间,他们要等待被显式的唤醒,否则会处于无限期等待的状态
- sleep()
5.计时等待(TIME_WAITING)
- 处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显式的唤醒,在达到一定时间后他们会自动唤醒
- sleep()
6.终止状态(TERMINATED)
- 1.当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为他终止了。这个线程对象也许是活的,但是他已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
- 2.在一个终止的线程上调用start())方法,会抛出java.lang.IllegalThreadStateException异常。
终止线程
package com.yishan.state;
1 | /** |
暂停sleep
sleep(时间)指定当前线程阻塞的毫秒数;
sleep存在异常InterruptedException;
sleep时间达到后线程进入就绪状态;
sleep可以模拟网络延时、倒计时等;
每一个对象都有一个锁,sleep不会释放锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package com.yishan.state;
/**
* sleep模拟网络延时,放大了发生问题的可能性
* @author : yishan
* @date : 2020-10-13 21:03
*/
public class BlockedSleep01 {
public static void main(String[] args) {
//一份资源
Web12306 web = new Web12306();
//多个代理
new Thread(web,"张三").start();
new Thread(web,"李四").start();
new Thread(web,"王二").start();
}
}
1 | class Web12306 implements Runnable{ |
1 | package com.yishan.state; |
1 | public static void test(String[] args) throws InterruptedException { |
礼让线程 yield
礼让线程,让当前正在执行线程暂停
不是阻塞线程,而是将线程从运行状态转入就绪状态
让cpu调度器重新调度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.yishan.state;
/**
* yield礼让线程,暂停线程 直接进入就绪状态 不是阻塞状态
* @author : yishan
* @date : 2020-10-15 13:29
*/
public class YieldDemo01 {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"a").start();
new Thread(myYield,"b").start();
}
}
class MyYield implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName()+"-->start");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"-->end");
}
}
1 | package com.yishan.state; |
插队 join
join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.yishan.state;
/**
* join合并线程,插队线程
* @author : yishan
* @date : 2020-10-15 13:44
*/
public class BlockedJoin01 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i=0;i<100;i++ ){
System.out.println("lambda.."+i);
}
});
t.start();
for (int i=0;i<100;i++){
if(i==20){
t.join();//插队 main被阻塞了 lambda执行完全才会执行main
}
System.out.println("main..."+i);
}
}
}
package com.yishan.state;
/**
- join的使用
- @author : yishan
- @date : 2020-10-15 13:44
- /
public class BlockedJoin02 {
public static void main(String[] args) {
}System.out.println("爸爸和儿子买烟的故事!"); new Thread(new Father()).start();
}
1 | class Father extends Thread{ |
重点
进入就绪状态的四种方式:
- 1.调用start()方法
- 2.sleep()/join(),IO流阻塞等解除进入就绪状态
- 3.在运行中让出CPU的调度直接进入就绪状态
- 4.JVM从本地线程切换到其他线程(内部算法进行切换)进入就绪状态
进入阻塞:
- 1.sleep
- 2.join
- 3.wait
- 4.read write等