码迷,mamicode.com
首页 > 编程语言 > 详细

线程生命周期

时间:2017-07-29 01:00:46      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:running   write   ted   try   ide   方法   返回   代码   class   

线程的生命周期:一个线程从创建到消亡的过程

如下图,表示线程生命周期中的各个状态:

技术分享

线程的生命周期可以分为五个状态:

1.创建状态:

  当用new操作符创建一个新的线程对象时,该线程处于创建状态。

  处于创建状态的线程只是一个空的线程对象,系统不为它分配资源。

2.可运行状态【runnable】:

  执行线程的start()方法将为线程分配必须的系统资源,安排其运行,并调用线程体——run()方法,

  这样就使得该线程处于可运行状态(Runnable)。

  这一状态并不是运行中状态(Running),因为线程也许实际上并未真正运行。

       注意:一个线程只有在start()之后才是具备可执行能力的(runnable状态的),但是具备可执行能力

     并不代表着会立即执行(running)一个线程,线程会等待着cpu的调度,只有在cpu调度了该

                  线程之后,该线程才会执行!换句话说:runnable状态的线程可能会立即执行,也可能不会

                  立即执行,只有当runnable状态的线程获得cpu调度执行权的时候才会立即执行!

3.正在执行状态【running】:

  需要注意的是:线程是被cpu调度的,多个线程或者多个进程之间的切换是由cpu来完成的!

4.阻塞状态:

  当发生下列事件时,处于运行状态的线程会转入到不可运行状态【阻塞状态】:

  调用了sleep()方法;

  线程调用wait()方法等待特定条件的满足;

  线程输入/输出阻塞。

  或者线程在抢锁的时候

  执行了yield()方法

  返回可运行状态:

  处于睡眠状态的线程在指定的时间过去后;

  如果线程在等待某一条件,另一个对象必须通过notify()或notifyAll()方法通知等待线程条件的改变;

  如果线程是因为输入输出阻塞,等待输入输出完成。

注意:1.当我们调用Thread.sleep()方法、wait()方法、yield()方法,也或者是争抢锁资源的时候 线程就会由running状态转到blocked【阻

    塞状态】,而一个线程进入阻塞【blocked】, 状态之后,是不能直接恢复到running状态的,它是需要先进入!

           2.另外running状态的线程除了可以通过blocked状态进入runnnable状态的情况外,处于running状态的线程还可以直接进入到runnable

    状态,这是因为cpu调度将执行权交给了其它线程了,多个线程或者多个进程之间的切换是由cpu来完成的!只不过速度很快,你看

    不出来而已,但是在某一个具体的时间点cpu只能执行一个线程!

5.消亡状态:

  当线程的run()方法执行结束后,该线程自然消亡。

   注意:最后一个状态是终结状态[disabled或者terminated]:当线程正常执行完毕或者也可能是从blocked状态的线程被打断的时候【比如

      sleep()、wait()、抢锁的时候被打断了】就会进入这种终结状态,也有可能由于操作系统的原因,线程会直接从runnable状态进入

      到terminated状态!

 

public class MultiThread {
	public static void main(String[] args) {
		new Thread("READ-THREAD"){
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
				readFromDataBase();
			}
		}.start();
		new Thread("WRITE-THREAD"){
			@Override
			public void run() {
				writeDataToFile();
			}
		}.start();
	}
	
	private static void readFromDataBase() {
		//read data from database and handle it
		try {
			println("begin read data from db.");
			Thread.sleep(1000*30L);
			println("read data done and handle it now");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		println("the data handle finish and successfully.");
	}
	
	private static void writeDataToFile(){
		//write data to file
		try {
			println("begin write data to file.");
			Thread.sleep(1000*30L);
			println("write data done and start handle it now");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		println("the data handle finish and successfully.");
	}
	private static void println(String message){
		System.out.println(message);
	}
	
}

 针对上面的代码,这里需要注意的是我们直接用匿名类对象直接调用的是start()方法,然后JVM虚拟机就会帮我们调用线程的run()方法,所以才会在

System.out.println(Thread.currentThread().getName());这段代码这里输出了READ-THREAD !如果我们不是用匿名对象,而是创建一个普通的对象,然后用
普通对象直接调用run()方法,也就如下:
		Thread t = new Thread("READ-THREAD"){
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
				readFromDataBase();
			}
		};
		//t.start()
		t.run();

 显然这是不可以的,因为如果我们直接用线程对象调用run()方法,而不是调用start()方法,那么此时该线程就相当于没启动,此时

    System.out.println(Thread.currentThread().getName());输出的将不再是READ-THREAD,而是main线程了!切记切记!

 

线程生命周期

标签:running   write   ted   try   ide   方法   返回   代码   class   

原文地址:http://www.cnblogs.com/python-machine/p/7253036.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!