四、线程状态
一、线程状态
操作系统中,线程被视为轻量级的进程,因此操作系统的线程状态与操作系统的进程状态是一致的
1. 线程五大状态
-
创建状态
Thread t = new Thread()线程对象一旦创建就进入到了新生状态 -
就绪状态
当调用
start()方法,线程会进入就绪状态,但不意味着立即执行 -
运行状态
进入运行状态,线程才会真正去执行线程体的代码
-
阻塞状态
当调用
sleep()、wait()或同步锁定时,线程进入阻塞状态,代码不会继续执行。等待阻塞事件解除后,重新进入就绪状态,等待CPU调度执行 -
死亡状态
线程中断或结束,一旦进入死亡状态就不能再启动

2. 线程中的一些方法
setPriority(int newPriority)更改线程的优先级static void sleep(long millis)在指定的毫秒数内让当前执行的线程休眠void join()合并线程并等待该线程终止再执行其他线程static void yield()暂停当前正在执行的线程,并执行其他线程void interrupt()中断线程(尽量别用)boolean isAlive()测试线程是否处于活动状态
二、操控线程
1. 停止线程
1.1 要点
- 不推荐使用 JDK 提供的
stop()、destory()等方法 - 推荐等待线程自己停止,例如使用
for循环限制次数,不建议死循环 - 建议使用一个标志位终止变量,例如当
flag == false时,终止线程运行
1.2 示例
public class TestStop implements Runnable {
// 1. 定义标识
private static boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println("run......Thread " + i++);
if (i >= 30) {
TestStop.stop();
System.out.println("该线程已停止");
}
}
}
// 2. 对外提供方法改变标识
public static void stop() {
flag = false;
}
public static void main(String[] args) {
TestStop t = new TestStop();
new Thread(t).start();
for (int i = 0; i < 100; i++) {
System.out.println("main线程 " + i);
}
}
}
2. 线程休眠
2.1 要点
sleep()中的参数指定当前线程阻塞的毫秒数sleep()方法存在异常InterruptedExceptionsleep()时间达到后线程进入就绪状态sleep()可以模拟网络延时、倒计时等- 每个对象都有一个锁,
sleep()不会释放锁
2.2 示例
例1. 模拟网络延迟,放大可能发生的问题的出现几率
public class TestSleep implements Runnable {
private int ticketNum = 10;
@Override
public void run() {
while (true) {
if (ticketNum <= 0) {
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNum-- + "张票");
}
}
public static void main(String[] args) {
TestSleep t = new TestSleep();
new Thread(t, "小明").start();
new Thread(t, "老师").start();
new Thread(t, "黄牛党").start();
}
}
例2. 模拟倒计时
public class TestSleep {
public static void tenDown() throws InterruptedException {
int num = 10;
while (true) {
Thread.sleep(1000);
System.out.println(num--);
if (num <= 0) {
break;
}
}
}
public static void main(String[] args) {
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. 线程礼让
3.1 要点
- 礼让线程,让当前正在执行的线程暂停
- 将线程从运行状态转为就绪状态
- 让 CPU 重新调度,礼让成功与否由 CPU 调度决定
3.2 示例
public class TestYield {
public static void main(String[] args) {
MyYield m = new MyYield();
new Thread(m, "a").start();
new Thread(m, "b").start();
}
}
class MyYield implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "线程停止执行");
}
}
4. 线程强制执行
4.1 要点
join合并线程,待此线程执行结束后,再执行其它线程。期间其它线程阻塞- 类似于现实生活中的插队
4.2 示例
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("插队线程 " + i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin t = new TestJoin();
Thread thread = new Thread(t);
thread.start();
for (int i = 0; i < 100; i++) {
if (i == 50) {
thread.join();
}
System.out.println("main方法线程 " + i);
}
}
}
三、观察线程状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("//////////");
});
Thread.State state = t.getState();
System.out.println(state);
// 观察启动后状态
t.start();
state = t.getState();
System.out.println(state);
// 线程执行期间重复监测
while (state != Thread.State.TERMINATED) {
Thread.sleep(100);
state = t.getState();
System.out.println(state);
}
}
}
四、扩展
Java线程的六个状态
NEW:新创建还未启动,指还未调用start()方法RUNNABLE:可运行,此状态的线程可能正在 Java 虚拟机中运行,也可能正在等待 CPU 分配资源,即包含了传统操作系统线程状态中的ready和runnig两个状态BLOCKED:被阻塞,该状态的下的线程正在等待锁释放以进入同步区WAITING:等待,该状态下的线程需要被其他线程唤醒才会转为RUNNABLE状态TIMED_WATING:计时等待,等待指定时间后会被唤醒TERMINATED:终止状态,线程已执行完毕

浙公网安备 33010602011771号