一、状态分类
1.新生状态:
用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间。通过调用start方法进入就绪状态(runable)
2.就绪状态:
处于就绪状态的线程已经具备了运行条件,但还么有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为:cpu调度。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。
3.运行状态
在运行状态的线程执行自己的run方法中代码,直到调用其他方法而终止,或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。
4.阻塞状态
处于运行状态的线程在某些情况下,如执行了sleep方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。
5.死亡状态
死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个,一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性的终止,如通过执行stop或者destory方法终止一个线程(不推荐使用这两个方法,前者会产生异常,后者是强制终止,不会释放锁)
二、停止线程
1.自然终止:线程体正常执行完毕
2.外部干涉:
1.线程类中,定义线程体使用的标识。
2.线程体使用该标识
3.对外提供方法改变标识。
4.外部根据条件调用该方法即可。
public class TestStop {
public static void main(String[] args) {
Study study = new Study();
new Thread(study).start();
//外部干涉
for(int i=0;i<100;i++){
if(50==i){
study.stop();//外部干涉
}
System.out.println("main....-->"+i);
}
}
}
class Study implements Runnable{
//1):线程类中定义线程体使用的标示
boolean flag = true;
@Override
public void run() {
//2)线程体使用该标示
while(flag){
System.out.println("study thread...");
}
}
//3)、对外提供方法改变标示
public void stop(){
this.flag = false;
}
}
三、阻塞
1、join:合并线程
public class TestJoin implements Runnable{
public static void main(String[] args) throws InterruptedException {
TestJoin join = new TestJoin();
Thread t = new Thread(join);//新生
t.start();//就绪
//cpu调度
for(int i=0;i<1000;i++){
if(i==50){
t.join();//mian阻塞...
}
System.out.println("main...."+i);
}
}
@Override
public void run() {
for(int i=0;i<1000;i++){
System.out.println("run...."+i);
}
}
}
2、yield:暂停自己的线程, static
public class TestYield implements Runnable{
public static void main(String[] args) {
TestYield yield = new TestYield();
Thread t = new Thread(yield);//新生
t.start();//就绪
//cpu调度
for(int i=0;i<1000;i++){
if(i%20==0){
Thread.yield();//暂停main线程
}
System.out.println("main...."+i);
}
}
@Override
public void run() {
for(int i=0;i<1000;i++){
System.out.println("run...."+i);
}
}
}
3、sleep:休眠,暂停当前线程,不释放锁。
1)与时间相关,倒计时
2)模拟网络延时
public class TestSleep {
public static void main(String[] args) throws InterruptedException {
//test1();
test2();
}
public static void test2() throws InterruptedException{
Date date = new Date(System.currentTimeMillis() + 10*1000);
long end = date.getTime();
while(true){
//输出
System.out.println(new SimpleDateFormat("mm:ss").format(date.getTime()));
//下一秒
Thread.sleep(1000);
//构建下一秒时间
date = new Date(date.getTime()-1000);
//10以内
if(date.getTime()<end-10000){
break;
}
}
}
//倒计时
public static void test1() throws InterruptedException{
int num=10;
while(true){
Thread.sleep(1000);
if(num<0){
break;
}
System.out.println(num);
num--;
}
}
}