并发编程学习总结(二) : 详解 线程的6种不同状态

来源:互联网 发布:交大知行大厦 邮编 编辑:程序博客网 时间:2024/06/06 18:25

(一) 线程状态:

我们先讨论一下线程的几种状态:

java中Thrad.State总共有6中状态:

(1)New (新创建)

(2)Runnable (可运行)

(3)Bolcked (被阻塞)

(4)Waiting (等待)

(5)Timed Waiting (计时等待)

(6)Terminated (被终止)


这里先列出各个线程状态发生的条件,下面将会对每种状态进行详细解析和代码实例。


下面我们分别看一下线程的这6中状态分别出现在什么情况下。

(1)New (新创建)

     当我们执行new Thread(target)时,jvm要为线程的运行做一些前期的准备工作,比如检查线程类是否已经被加载、解析和初始化过,接下来还要为对象分配空间并对空间

初始化零值,接下来还要对对象进行一些类的元数据信息、对象的GC分年代等的设置信息等。当完成这些准备工作时线程才能进入到下一个Runnable (可运行)状态。所以说

当业务需要频繁创建线程时,最好使用线程池,提高效率减轻JVM的压力。当然如果大量线程进行频繁上下文切换,此时多线程的效率会大打折扣。

public class ThreadTask {public void concreteTask() {System.out.println("线程开始执行");long beginTime = System.currentTimeMillis();System.out.println("线程正在执行具体任务");// 等待5秒钟 模拟线程执行任务时间while(System.currentTimeMillis() - beginTime < 5000) {}System.out.println("线程执行完毕");}}public class ThreadStateTest {public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stubfinal ThreadTask tt = new ThreadTask();//new Thread对象Thread thread1 = new Thread(new Runnable(){public void run() {tt.concreteTask();}},"newThread1");// 输出线程的状态System.out.println(thread1.getState());}}输出:NEW


(2)Runnable (可运行)

一旦调用线程的start()方法,线程就处于可运行状态。一个处于可运行状态的线程 可能正在运行 ,也可能正在等待操作系统为其分配cpu执行时间。我们将上面的代码添加一行代码thread1.start();

public class ThreadStateTest {public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stubfinal ThreadTask tt = new ThreadTask();//new Thread对象Thread thread1 = new Thread(new Runnable(){public void run() {tt.concreteTask();}},"newThread1");// 启动线程thread1.start();// 输出线程的状态System.out.println(thread1.getState());}}
输出:线程开始执行线程正在执行具体任务RUNNABLE线程执行完毕

(3)Bolcked (被阻塞)

当一个线程试图获取内部对象锁(而不是java.util.cncurrent库中的锁),而该锁被其他线程持有,当所有其他线程释放锁,并且线程调度器运行

本线程持有锁时,该线程将变成非阻塞状态。

public class ThreadTask {private Object lock = new Object();public void concreteTask()   {synchronized(lock) {System.out.println(Thread.currentThread().getName()+"线程开始执行");System.out.println(Thread.currentThread().getName()+"线程正在执行具体任务");// 模拟线程耗时操作long beginTime = System.currentTimeMillis();while(System.currentTimeMillis() - beginTime < 5000) {}System.out.println(Thread.currentThread().getName()+"线程执行完毕");}}public void setFlag() {synchronized(lock) {System.out.println(Thread.currentThread().getName()+"has set true");}}}public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stubfinal ThreadTask tt = new ThreadTask();//new Thread对象Thread thread1 = new Thread(new Runnable(){public void run() {tt.concreteTask();}},"newThread1");Thread thread2 = new Thread(new Runnable(){public void run() {tt.setFlag();}},"newThread2");thread1.start();thread2.start();    Thread.sleep(1000);// 输出线程的状态System.out.println(thread1.getName() + ":" + thread1.getState());System.out.println(thread2.getName() + ":" + thread2.getState());}}输出:newThread1线程开始执行newThread1线程正在执行具体任务newThread1:RUNNABLEnewThread2:BLOCKEDnewThread1线程执行完毕newThread2has set true

(4)Waiting (等待)

当线程等待另一个线程通知调度器一个条件时,这个线程就进入了等待状态。在调用Object.wait()方法或者Thread.join()方法,或等待java.util.concurrent库中的Lock或Condition时都会进入到等待状态。

调用join()方法

public class ThreadTask {public void concreteTask()   {System.out.println(Thread.currentThread().getName()+"线程开始执行");System.out.println(Thread.currentThread().getName()+"线程正在执行具体任务");Thread thread2 = new Thread(new Runnable(){public void run() {System.out.println("newThread2 is running");// 模拟线程耗时操作long beginTime = System.currentTimeMillis();while(System.currentTimeMillis() - beginTime < 5000) {}System.out.println("newThread2 is stop");}},"newThread2");thread2.start();try {thread2.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"线程执行完毕");}}public class ThreadStateTest {public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stubfinal ThreadTask tt = new ThreadTask();//new Thread对象Thread thread1 = new Thread(new Runnable(){public void run() {tt.concreteTask();}},"newThread1");thread1.start();Thread.sleep(1000);// 输出线程的状态System.out.println(thread1.getName() + ":" + thread1.getState());}}输出:newThread1线程开始执行newThread1线程正在执行具体任务newThread2 is runningnewThread1:WAITINGnewThread2 is stopnewThread1线程执行完毕

等待java.util.concurrent库中的Lock时 进入等待状态

public class ThreadTask {private Object lock = new Object();private ReentrantLock reLock = new ReentrantLock();    public void concreteTask()   {reLock.lock();try{System.out.println(Thread.currentThread().getName()+"线程开始执行");System.out.println(Thread.currentThread().getName()+"线程正在执行具体任务");// 模拟线程耗时操作long beginTime = System.currentTimeMillis();while(System.currentTimeMillis() - beginTime < 5000) {}System.out.println(Thread.currentThread().getName()+"线程执行完毕");}finally {reLock.unlock();}}public void setFlag() {reLock.lock();try{System.out.println(Thread.currentThread().getName()+"has set true");}finally {reLock.unlock();}}}public class ThreadStateTest {public static void main(String[] args) throws InterruptedException {// TODO Auto-generated method stubfinal ThreadTask tt = new ThreadTask();//new Thread对象Thread thread1 = new Thread(new Runnable(){public void run() {tt.concreteTask();}},"newThread1");Thread thread2 = new Thread(new Runnable(){public void run() {tt.setFlag();}},"newThread2");thread1.start();thread2.start();        Thread.sleep(1000);// 输出线程的状态System.out.println(thread1.getName() + ":" + thread1.getState());System.out.println(thread2.getName() + ":" + thread2.getState());}}输出:newThread1线程开始执行newThread1线程正在执行具体任务newThread1:RUNNABLEnewThread2:WAITINGnewThread1线程执行完毕newThread2has set true


(5)Timed Waiting (计时等待)

同Waiting(等待)状态,有几个方法有超时参数,调用他们将进入计时状态。这一状态将一直保持到超时期满或者接收到适当通知。带有超时参数的方法有Thread.sleep() 、Object.wait()、Thread.join()、Lock.tryLock()、Condition.await()。


(6)Terminated (被终止)

线程因如下两个原因之一将被终止:

  1. run()方法正常退出而自然死亡
  2. 一个没有捕获的异常终止了run()方法而意外死亡






0 0
原创粉丝点击