1、java里线程状态概述
在java中,使用Thread.currentThread().getState()可以查看当前线程的状态。
而java中的线程状态可以概括为以下六种
1. NEW :
当线程对象被创建时,它处于新建状态。此时,线程还没有开始执行。
2. RUNNABLE :
在调用线程的 start() 方法后,线程进入可运行状态。表示线程已经准备好执行,但可能还未获得 CPU 时间片来执行。
- 包括READY和RUNNING两种细分状态
3. WAITING:
线程在等待其他线程发出特定信号或条件时进入等待状态。线程可以通过 wait() 方法或其他类似的方法使自己进入等待状态。
4. TIMED WAITING:
类似于等待状态,但在等待一段特定的时间后会自动返回可运行状态。线程可以通过 sleep() 方法、join() 方法或其他类似的方法进入计时等待状态。
5. BLOCKED:
线程在某些情况下无法继续执行时,进入阻塞状态。这可能是由于等待某个资源、等待锁的释放、等待输入/输出操作完成等原因。
6. TERMINATED:
线程结束
2、编程实现线程各种状态
1)、工具类准备
主要是控制线程的睡眠时间,可以控制线程的唤醒顺序,自主控制线程对资源的利用顺序。
定义一个静态辅助类 SleepHelper,
其中包含了两个静态方法 sleepSeconds 和 sleepMilli,用于实现线程的睡眠功能。
sleepSeconds方法接受一个整数参数seconds,表示需要睡眠的秒数。通过调用TimeUnit.SECONDS.sleep(seconds)方法,让当前线程睡眠指定的秒数。sleepMilli方法接受一个整数参数i,表示需要睡眠的毫秒数。通过调用TimeUnit.MILLISECONDS.sleep(i)方法,让当前线程睡眠指定的毫秒数。
这些方法提供了一种方便的方式来使当前线程睡眠一段时间,以控制线程的执行速度、时间间隔或延迟等操作。
public static class SleepHelper {
public static void sleepSeconds(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void sleepMilli(int i) {
try {
TimeUnit.MILLISECONDS.sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2)、线程状态代码实现
(1)、线程创建和线程运行
// 创建一个线程并在内部输出当前状态,只有线程运行时才会进入到内部执行代码,所以输出结果为 RUNNABLE
Thread t1 = new Thread(() -> {
System.out.println("2:" + Thread.currentThread().getState());
for (int i = 0; i < 3; i++) {
SleepHelper.sleepSeconds(1);
System.out.print(i + " ");
}
System.out.println();
});
// 此时创建线程输出结果为NEW
System.out.println("1:" + t1.getState());
// 线程唤醒此时进入到上面的lambda语句块中
t1.start();
// 线程结束
t1.join();
// 线程结束输出TERMINATED
System.out.println("3:" + t1.getState());
2)、线程的WAITING和TIMED WAITING
// 在创建时给线程加上锁,控制线程为WAITING
Thread t2 = new Thread(() -> {
try {
LockSupport.park();
System.out.println("t2 go on!");
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 此时启动线程
t2.start();
// 使用工具使线程等待一秒,确保线程已经完全启动
TimeUnit.SECONDS.sleep(1);
// 此时输出线程状态,结果为WAITING
System.out.println("4:" + t2.getState());
// 在此时给线程释放锁
LockSupport.unpark(t2);
// 等待一秒,确保线程的Lock被完全释放
TimeUnit.SECONDS.sleep(1);
// 由于线程内部也在睡眠并且时间为5秒,但是线程已经获得资源,所以线程此时的状态为TIMED WAITING
System.out.println("5:" + t2.getState());
3)、线程的BLOCKED
final Object o = new Object();
// 创建线程时请求获取资源o
Thread t3 = new Thread(() -> {
synchronized (o) {
System.out.println("t3 得到了锁 o");
}
});
// 创建另一个线程,直接启动,占用资源o五秒,
new Thread(() -> {
synchronized (o) {
SleepHelper.sleepSeconds(5);
}
}).start();
// 主程序睡眠1秒,确保上面占用资源的线程启动
SleepHelper.sleepSeconds(1);
// 启动t3线程
t3.start();
// 睡眠一秒确保线程完全启动
SleepHelper.sleepSeconds(1);
// 此时t3请求o资源被占用,线程是BLOCKED状态
System.out.println("6:" + t3.getState());
3、整体代码
public static void main(String[] args) throws Exception {
//===================================================
// 创建一个线程并在内部输出当前状态,只有线程运行时才会进入到内部执行代码,所以输出结果为 RUNNABLE
Thread t1 = new Thread(() -> {
System.out.println("2:" + Thread.currentThread().getState());
for (int i = 0; i < 3; i++) {
SleepHelper.sleepSeconds(1);
System.out.print(i + " ");
}
System.out.println();
});
// 此时创建线程输出结果为NEW
System.out.println("1:" + t1.getState());
// 线程唤醒此时进入到上面的lambda语句块中
t1.start();
// 线程结束
t1.join();
// 线程结束输出TERMINATED
System.out.println("3:" + t1.getState());
//===================================================
Thread t2 = new Thread(() -> {
try {
LockSupport.park();
System.out.println("t2 go on!");
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t2.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("4:" + t2.getState());
LockSupport.unpark(t2);
TimeUnit.SECONDS.sleep(1);
System.out.println("5:" + t2.getState());
//===================================================
final Object o = new Object();
Thread t3 = new Thread(() -> {
synchronized (o) {
System.out.println("t3 得到了锁 o");
}
});
new Thread(() -> {
synchronized (o) {
SleepHelper.sleepSeconds(5);
}
}).start();
SleepHelper.sleepSeconds(1);
t3.start();
SleepHelper.sleepSeconds(1);
System.out.println("6:" + t3.getState());
//===================================================
final Lock lock = new ReentrantLock();
Thread t4 = new Thread(() -> {
lock.lock(); //省略try finally
System.out.println("t4 得到了锁 o");
lock.unlock();
});
new Thread(() -> {
lock.lock();
SleepHelper.sleepSeconds(5);
lock.unlock();
}).start();
SleepHelper.sleepSeconds(1);
t4.start();
SleepHelper.sleepSeconds(1);
System.out.println("7: " + t4.getState());
//===================================================
//===================================================
Thread t5 = new Thread(() -> {
LockSupport.park();
});
t5.start();
SleepHelper.sleepSeconds(1);
System.out.println("8: " + t5.getState());
LockSupport.unpark(t5);
}