目录
一、线程状态:NEW、RUNNABLE、TERMINATED
线程运行状态图解:
一、线程状态:NEW、RUNNABLE、TERMINATED
NEW:新建状态,线程中的任务代码还没有开始执行,如new Mythread(),此时处于新建状态,新建状态的线程没有执行start()方法
RUNNABLE:就绪状态,即可运行状态;当线程调用了start()方法,当前线程进入可运行状态,可运行状态并不立即执行run()方法,它还需要于其他线程争夺CPU的使用权限。
RUNNING:运行状态,获取到CPU使用权,执行run()方法;线程只能从可运行状态进入运行状态
TERMINATED:停止状态,线程执行完或因异常退出run()方法,该线程的生命周期结束
测试代码:
public class Mythread extends Thread {
public Mythread() {
System.out.println("线程名称:" + currentThread().getName()
+ ",构造方法中的状态:" + Thread.currentThread().getState()
+ ",线程是否存活:" + Thread.currentThread().isAlive());
}
@Override
public void run() {
System.out.println("线程名称:" + currentThread().getName()
+ ",Run方法中的状态:" + Thread.currentThread().getState()
+ ",线程是否存活:" + Thread.currentThread().isAlive());
}
public static void main(String[] args) throws InterruptedException {
Mythread mythread = new Mythread();
System.out.println("线程名称:" + mythread.getName()
+ ",实例化对象后的状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
Thread.sleep(1000);
mythread.start();
Thread.sleep(1000);
System.out.println("线程名称:" + mythread.getName()
+ ",线程运行结束后状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
}
}
执行结果如下图:
二、线程状态:TIME_WATING(限时等待)
TIME_WATING:限时等待状态;线程执行了诸如Thread.sleep()或带有时间设定的Thread.join()、Object.wait()等方法时的等待状态,超过设定的等待时间,等待线程会自动唤醒,进入阻塞状态(Blocked)或者可运行状态(RUNNABLE)。
测试代码:
public class Mythread extends Thread {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Mythread mythread = new Mythread();
mythread.start();
Thread.sleep(1000);
// 打印下边语句的时候,线程还在睡眠当中
System.out.println("线程名称:" + mythread.getName()
+ ",线程运行结束后状态:" + mythread.getState()
+ ",线程是否存活:" + mythread.isAlive());
}
}
执行结果:
三、线程状态:BLOCKED(等待锁)
BLOCKED:阻塞状态,线程获取锁失败,会加入线程等待锁的同步阻塞队列,进入阻塞状态。该阻塞线程在获取锁后,会进入可运行状态(RUNNABLE),这里需要记住,线程是不能直接由非就绪状态进入运行状态的。
1、创建带同步方法的MyService类:
public class MyService {
public synchronized void serviceMethod() {
try {
System.out.println(Thread.currentThread().getName()+":执行serviceMethod方法中...");
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2、创建线程A和线程B:
线程A:
public class MyThreadA extends Thread {
private MyService myService;
public MyThreadA(MyService myService){
super();
this.myService = myService;
}
@Override
public void run() {
myService.serviceMethod();
}
}
线程B:
public class MyThreadB extends Thread {
private MyService myService;
public MyThreadB(MyService myService){
super();
this.myService = myService;
}
@Override
public void run() {
myService.serviceMethod();
}
}
3、执行方法:
public static void main(String[] args) throws InterruptedException {
MyService myService = new MyService();
MyThreadA mythreadA = new MyThreadA(myService);
mythreadA.setName("线程A");
mythreadA.start();
MyThreadB mythreadB = new MyThreadB(myService);
mythreadB.setName("线程B");
mythreadB.start();
// 打印线程B的状态
System.out.println("线程名称:" + mythreadB.getName()
+ ",线程运行状态:" + mythreadB.getState()
+ ",线程是否存活:" + mythreadB.isAlive());
}
执行结果:
注:此处运行是处于就绪状态(RUNNABLE),sleep()方法不会释放锁,在只有一个对象锁的情况下,线程B是不会拿到锁的,所以这个状态应该是阻塞状态。
四、线程状态:WAITING(条件等待状态)
WAITING:又叫条件等待状态,当线程的运行条件不满足时,通过锁的条件等待机制(调用锁对象的wait()或显示锁条件对象的await()方法)让线程进入等待状态(WAITING)。处于等待状态的线程将不会被cpu执行,除非线程的运行条件得到满足后,其可被其他线程唤醒,进入阻塞状态(Blocked)。调用不带超时的Thread.join()方法也会进入等待状态。
1、创建锁对象:
注:一般情况下,不建议用String作为锁,在此为方便只作示例
因为在JVM中具有String常量池(如果两个String具有相同的值,那么他们的地址是相同的,都保存在这个常量池中)。当以String作为锁的时候,如果值相同则,那么线程持有相同的锁。这样就造成了另外一个线程不能执行。
public class MyLock {
public static final String lock = "lock";
}
2、创建线程类和执行main()方法:
public class MyThread extends Thread {
@Override
public void run() {
synchronized (MyLock.lock){
try {
MyLock.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
myThread.start();
Thread.sleep(1000);
System.out.println("线程名称:" + myThread.getName()
+ ",线程运行状态:" + myThread.getState()
+ ",线程是否存活:" + myThread.isAlive());
}
}
执行结果:
五、isAlive()方法
isAlive()方法是测试线程是否处于活动状态。从以上线程运行状况和结果可以得知,只有当线程在新建(NEW)和销毁(TERMINATED)状态时,线程的存活状态为false,其他时候线程始终处于活动状态。