30 多线程(三)——进程的五大状态及主动转换状态方法
线程的五大状态
线程的五大状态为:
- 新生状态
- 就绪状态
- 运行状态
- 阻塞状态
- 死亡状态
图示一:
图示二:
改变线程状态的方法
新生线程 :new Thread()
就绪状态:start()方法进入就绪状态,阻塞结束进入就绪状态
运行状态:通过cpu调度算法将就绪状态的线程按优先级进行调用运行
手动停止线程进入 死亡状态
Thread类中提供了stop与destroy方法可以用来停止线程,但已经弃用,它们会造成死锁,停止线程的方法现在使用手写标识方法。
// 1.定义标记 线程终止标记 // 2.关联标记 // 3.对外提供方法 改变标记
// 4.调用终止方法
举个例子:
package _20191203; public class TerminalThread implements Runnable{ boolean flag = false; // 1.定义标记 线程终止标记 public static void main(String[] args) { TerminalThread t = new TerminalThread(); new Thread(t).start(); for(int i=0;i<100;i++) { if(i==80) { t.terminal();// 4.调用终止方法 } System.out.println("main--->"+i); } } @Override public void run() { int i =0; while(!flag) { //2.关联标记 System.out.println("thread--->"+i); i++; } } public void terminal() {// 3.对外提供方法 改变标记 flag = true; } }
阻塞状态 sleep()方法(sleep方法只是进入阻塞的方法之一)
- sleep(毫秒数) 指定当前线程阻塞的毫秒数
- sleep()是写在run()方法里的
- sleep存在异常InterruptedException 但不能通过run()方法声明,只能直接try-catch
- sleep时间达到后线程进入就绪状态
- sleep可以模拟网络延时、倒计时等
- 每一个对象都有一个锁,sleep不会释放锁
线程礼让(暂停) yield方法
- 礼让线程实际上是将线程从运行状态转到就绪状态,而不是阻塞状态
- 避免线程占用cpu过久
举个例子:
package _20191204; /** * 礼让线程:yield() 让线程进入就绪状态 * @author UID * */ public class Demo02_yield{ public static void main(String[] args) { new Thread(new MyYield(),"线程1").start(); new Thread(new MyYield(),"线程2").start(); } } class MyYield implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"-->start"); Thread.yield(); System.out.println(Thread.currentThread().getName()+"-->end"); } }
线程插队 join()方法
- join方法需要有一个具体的线程对象调用,不能直接用Thread调用
- join()写在哪个方法里,哪个方法所在的线程就被 调用join()的线程对象 插队
格式:
join() //无时间限制插队,一直到线程执行完毕 join(long millis) //被插队的线程等待millis毫秒,时间结束后,两个线程并发
举个例子
package _20191204; /** * join() 线程插队 * @author UID * */ public class Demo03_join02 { public static void main(String[] args) { Father f = new Father(); f.start(); } } class Father extends Thread{ public void run() { System.out.println("爸爸想抽烟..."); System.out.println("没烟了,叫儿子去买..."); Son s = new Son(); s.start(); try { s.join(3000);//关键性的一句,使被插队的线程等待3000毫秒
//s.join();//被插入的线程无限等待 直到插入的线程执行完毕 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }// System.out.println("爸爸接过烟,摸了摸儿子的头..."); System.out.println("小兔崽子让我等了这么久!"); } } class Son extends Thread{ public void run() { System.out.println("儿子接过钱出门了..."); System.out.println("儿子路过游戏厅..."); for(int i = 10;i > 0;i--) { System.out.println("打游戏中..."+i+"分钟"); try { sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("赶紧买烟去..."); System.out.println("儿子回到家..."); } }
join()中的毫秒数结束后,插入线程与被插入的线程并发,争用cpu
Thread中的线程状态枚举Thread.State
可以通过getState()方法获取状态