新生
用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态。
注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常。
就绪
就绪状态的线程具备了运行的条件,但是还没有分配到cpu,在就绪队列当中
等待状态也不是运行状态,只有当系统选中一个的等待执行的thread对象后,就会进入到执行状态,这个过程就是cpu调度,
运行
1 处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。
-
也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。
-
如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。 当发生如下情况是,线程会从运行状态变为阻塞状态: ①、线程调用sleep方法主动放弃所占用的系统资源 ②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞 ③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有 ④、线程在等待某个通知(notify) sleep()方法模拟阻塞 ```java
package jucdemo;
/**
-
@author 邓亚非
*/
public class Person extends Thread {private String name;
public Person(String name){
this.name=name;
}@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(this.name+“跑了”+i+“米”);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
阻塞
阻塞状态是一个很棘手的问题,因为让一个线程进入阻塞状态的方式非常得多
处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。阻塞的情况分三种:
```
其它阻塞
运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
```
同步阻塞
正在运行的线程遇到对象的同步锁时,会进入到锁池状态,获得锁资源,锁资源获取到后会重新进入到就绪状态等待CPU分配资源准备执行。
如果线程在获取同步锁时,该同步锁(synchronized)被别的线程占用,则JVM会把该线程放入锁池中。
阻塞状态消除后会进入就绪的状态不会到运行状态
等待阻塞
-
运行的线程执行wait()方法,JVM会把该线程放入等待池中。
死亡
前面我们知道,线程在正常结束和遇到没有抛出的异常会进入死亡状态,注意sleep方法不会让它进入死亡状态
package jucdemo;
/**
* @author 邓亚非
*/
public class Person extends Thread {
private String name;
public Person(String name){
this.name=name;
}
@Override
public void run() {
for (int i=1;i<=10;i++){
System.out.println(this.name+"跑了"+i+"米");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
String string=null;
System.out.println(string.length());
}
}
}
我们给它一个空指针异常,她就会进入到死亡状态