30 多线程(三)——进程的五大状态及主动转换状态方法

线程的五大状态

线程的五大状态为:

  1. 新生状态
  2. 就绪状态
  3. 运行状态
  4. 阻塞状态
  5. 死亡状态

图示一:

图示二:

改变线程状态的方法

新生线程 :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()方法获取状态

 

posted @ 2019-12-03 17:38  Scorpicat  阅读(479)  评论(0编辑  收藏  举报