博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
1.线程生命周期
阅读量:5023 次
发布时间:2019-06-12

本文共 3331 字,大约阅读时间需要 11 分钟。

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

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

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

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线程了!切记切记!

 

 

另外,我们这里也总结一下其它的:

1.我们知道,进程中包括线程,线程才是真正干事的,也就是说一个进程中至少有一个线程(main线程或者主线程),这个线程是被JVM调用的,而且线程的名字就是main!

2.实现一个线程,必须创建Thread实例,覆写里面的run方法,并且调用start()方法!这里需要注意:如果我们不调用run方法,那么这个类就是一个普通的实例类,不是多线程!

3.当调用了一个线程的start()方法之后,此时至少存在两个线程,一个是调用线程的main线程【也就是调用线程的线程】,再一个是这个线程!

4.线程的生命周期分为:new ,runnable,running,block,terminate等几部分!

 

转载于:https://www.cnblogs.com/python-machine/p/7253036.html

你可能感兴趣的文章
.NETFramework:template
查看>>
HM16.0之帧内模式——xCheckRDCostIntra()函数
查看>>
Jmeter性能测试 入门
查看>>
安卓动画有哪几种?他们的区别?
查看>>
Nodejs学习总结 -Express入门(一)
查看>>
web前端优化
查看>>
ssh 连接原理及ssh-keygen
查看>>
vs2013编译qt程序后中文出现乱码
查看>>
【转】IOS数据库操作SQLite3使用详解
查看>>
Android官方技术文档翻译——ApplicationId 与 PackageName
查看>>
设计网站大全
查看>>
JVM CUP占用率过高排除方法,windows环境
查看>>
【转】JAVA字符串格式化-String.format()的使用
查看>>
【转】ButterKnife基本使用--不错
查看>>
【转】VS2012编译出来的程序,在XP上运行,出现“.exe 不是有效的 win32 应用程序” “not a valid win32 application”...
查看>>
函数中关于const关键字使用的注意事项
查看>>
微信架构(转)
查看>>
Web项目中的路径问题
查看>>
js随机数的取整
查看>>
关于解析漏洞
查看>>