Java线程状态转换

7 篇文章 0 订阅
5 篇文章 0 订阅

 


 

在任意一个时间点:一个线程只能有且只有其中一种状态。

 

 

新建(new)状态:创建后尚未启动的线程就是出于这种状态。

 

运行(Runable)状态:Runable包括了操作系统线程状态中的Running和Ready,也就是出于此状态的线程有可能正在执行,也有可能等待CPU为它分配执行时间。

 

无限期等待(waiting)状态:处于该状态下的线程不会被分配CPU执行时间,它们要等待被其他线程显示的唤醒。以下的方法会让线程陷入无限期的等待状态。

 

  1. 没有设置timeout参数的Object.wait()方法。
  2. 没有设置timeout参数的Thread.join()方法
  3. LockSupport.park()方法。

 

 

限期等待(Timed Waiting)状态:处于该状态下的线程不会被分配CPU执行时间,但是不需要等待其他线程显式的唤醒。而是在一定时间之后它们会由系统自动唤醒。一以下方法会让线程进入限期等待的状态:

 

  1. Thread.sleep()方法
  2. 设置了timeout参数的Object.wait()方法
  3. 设置了timeout参数的Thread.join()方法
  4. LockSupport.parkNanos()方法
  5. LockSupport.parkUntil()方法

 

 

阻塞(blocked)状态:阻塞状态,顾名思义就是线程被阻塞了,在程序等待进入同步区域的时候,线程将进入这种状态。“阻塞状态” 和“等待状态” 的区别:“阻塞状态”在等待着获取一个排它锁。如果另一个线程获得了排它锁,然而这个线程申请获得这个排它锁的时候就会进入“阻塞状态”。“等待状态”则是在等待一段时间后,或者有唤醒动作的发生。

 

结束(terminated)状态:已终止线程的线程状态。线程结束执行。

线程状态转换关系如图(图来自深入理解jvm虚拟机)

 

 

接下来就是说明让线程进入等待状态的一些方法:

1、Object类

Object.wait()方法:让当前线程立即释放当前获得的锁并进入无限等待状态。

 

Object.wait(long timeout)方法:让当前线程立即释放当前获得的锁并进入限期等待状态,timeout参数的单位是毫秒。唤醒:①其他线程调用notify() 或者notifyAll()、②超过timeout毫秒之后由系统自动唤醒。

 

Object.wait(long timeout,int naos)方法:同wait(long timeout)方法,多出来的naos参数则是单位则是纳秒,所以如果被系统自动唤醒时间是:(timeout*1000000+naos)纳秒

 

notify()方法:随机唤醒一个处于“等待状态”的线程(API文档上If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation)。

 

notifyAll()方法:唤醒所有处于“等待状态”的线程。然后所有的线程去竞争这个排他锁(优先级高的线程获得的锁的概率大)。无论notify()方法还是notifyAll()方法不会立即释放获得的锁,而是等同步代码块执行完毕后才会释放锁。

 

注意:wait方法和notify方法必须是同一个锁才行。

wait方法和notify方法必须在同步代码块中使用。

2、Thread类

Thread.join()方法:等待当前线程执行完毕后再执行join()后面的代码。eg:t1.join()就是等待t1线程执行完毕后,再执行后面的代码。

 

Thread.join(long millis)方法:至多等待millis毫秒当前线程执行,超过这个时间后,系统会主动notifyAll。

 

Thread.join(longmillis,int naos)方法:至多等待millis毫秒+naos纳秒当前线程执行,超过这个时间后,系统会主动notifyAll。

 

 

 

 

package com.cn.hn.test;

public class ThreadSimple implements Runnable{
	public void run(){
		
		System.out.println(Thread.currentThread().getName()+"begin:"+ System.nanoTime());
		try {
			Thread.sleep(1800);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"end:"+ System.nanoTime());

	};
	public static void main(String[] args){
		ThreadSimple test1 = new ThreadSimple();
		Thread t1 = new Thread(test1);
		Thread t2 = new Thread(test1);
		t1.setName("test1");
		t2.setName("test2");
		System.out.println("main"+Thread.currentThread().getName()+System.nanoTime());
		t1.start();
		try {
			t1.join();
			//t1.join(100);
			t2.start();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("main"+Thread.currentThread().getName()+System.nanoTime());
	}

}

 

 

 

Thread.sleep(long millis)方法:让当前执行线程睡眠millis毫秒。超过这个时间后,系统会主动notify该线程。

 

Thread.sleep(long millis ,int naos)方法:让当前执行线程睡眠millis毫秒+naos纳秒,超过这个时间后,系统会主动notify该线程。

 

注意:sleep()方法并不释放当前线程持有的锁,只是让当前线程让出CPU,并陷入睡眠状态

 

Thread.run()方法,一个线程的执行逻辑。调用Thread.start()方法会执行run()方法的内容。该方法没有返回值。如果要求有返回值,可以使用Callable()。

 

Thread.start()方法:启动一个线程。进入Ready状态,如果获取了cpu执行时间。然后会调用run()方法.

 

Thread.yield()方法:当前线程让出CPU执行时间,然后处于ready状态。然后该线程和其他处于ready状态的线程一起竞争CPU执行时间。

 

Thread.interrupt()方法:尝试去中断该线程。它会将当前线程中断标志位设置为TRUE。至于是否中断以及中断的过程,再开一篇说好了。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值