java线程的几种状态详解

线程状态和sleep/yieId/join/stop/destroy方法

新生状态

         用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable

就绪状态

         处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“CPU调度”。一旦获得CPU,线程就进入运行并自动调用自己的run方法。

运行状态

         在运行状态的线程执行自己的run方法中代码,直到调用其他方法而终止、或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片没有执行结束,就会被系统给换下来回到等待执行状态

死亡状态

         死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性地终止,如通过执行stop或destroy方法来终止一个线程。

                   Method  stop()&destroy()  in  the  class  Thread  is  deprecated

         当一个线程进入死亡状态以后,就不能再回到其他状态了,让一个Thread对象重新执行一次的唯一方法,就是重新产生一个Thread对象。

终止线程的典型方法

public class TestThreadCiycle implements Runnable {
	String name;
	boolean live = true;
	public TestThreadCiycle(String name) {
		super();
		this.name = name;
	}
	public void run() {
		int i = 0;
		while(live){
			System.out.println(name + (i++));
		}
	}
	
	public void terminate(){
		live = false;
	}
	
	public static void main(String[] args) {
		TestThreadCiycle ttc = new TestThreadCiycle("线程A:");
		Thread t1 = new Thread(ttc);
		t1.start();
		for(int i=0;i<1000;i++){
			System.out.println(i);
		}
		ttc.terminate();
		System.out.println("ttc stop!");
	}
}

阻塞状态(sleep/yield/join)方法

         处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备资源,将让出CPU并暂且停止自己的运行,进入阻塞状态。

  1. 在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。
  2. 有三种方法可以暂停Thread执行:
    1. sleep方法:sleep时别的线程也不可以访问锁定对象。
    2. yield方法:让出CPU的使用权,从运行状态直接进入就绪态。让CPU重新挑选哪一个线程进入运行状态。
    3. join方法:当某个线程等待另一个线程执行结束后,才继续执行时,使用join方法。使调用该方法的线程在此之前执行完毕,也就是等待调用该方法的线程执行完毕后再往下继续执行。
public class TestThreadState {
		public static void main(String[] args) {
			//使用继承方式实现多线程
	//		StateThread thread1 = new StateThread();
	//		thread1.start();
	//		StateThread thread2 = new StateThread();
	//		thread2.start();
			
			System.out.println("老爸和儿子买烟的故事");
			Thread father = new Thread(new FatherThread());
			father.start();
		}
	}

	class StateThread extends Thread{
		public void run(){
			for (int i = 0; i < 100; i++) {
				System.out.println(this.getName() + ":" + i);
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				Thread.yield();
			}
		}
	}

	class FatherThread implements  Runnable{
		public void run() {
			System.out.println("老爸想抽烟,才发现烟抽完了");
			System.out.println("老爸让儿子去买包烟去");
			Thread son = new Thread(new SonThread());
			son.start();
			System.out.println("老爸等儿子买烟回来");
			try {
				son.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("老爸出门去找儿子跑哪儿去了");
				System.exit(1);// 结束JVM。如果是0则表示正常结束;如果是非0则表示非正常结束
			}
			System.out.println("老爸高兴的接过烟开始抽,并把零钱给了儿子");
		}
	}

	class SonThread  implements  Runnable{
		@Override
		public void run() {
			System.out.println("儿子出门去买烟");
			System.out.println("儿子买烟需要10分钟");
			try {
				for (int i = 0; i <= 10; i++) {
					System.out.println("第"+ i +"分钟");
					Thread.sleep(1000);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("儿子买烟回来了");
			
		}
	}

总结:

new:创建好线程对象,但没有启动的时候。

一个线程的调用start()之后不一定会马上启动,此时进入就绪状态,等待得到资源。

就绪线程通过scheduler(调度程序)去确定是否运行

Runing---dead:运行结束(非双向,为单向箭头)

Runing---就绪:暂停(除了没有CPU,具备运行的所有条件)

Runing---otherwise(阻塞):因程序原因:调用sleep或join之后,线程被阻塞,这时不具备运行的条件,此时线程进入阻塞池。Sleep或join条件解除之后直接进入Runnable不进入runing

Lock Pool:锁池状态。每个对象都有自己的锁池,锁池里放置了想获得对象锁的线程。

等待状态(wait pool):比如一个线程调用了某个对象的wait()方法,就进入该对象的wait pool,正在等待其他线程调用这个对象的notify或者notifyAll()(这两个方法同样是继承自Objet类)方法来唤醒它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值