序言

闲来无事,记录学习历程,交个朋友。欢迎讨论碰撞,产生好的解决方案!!!👏👏👏

背景

学习一下Java的线程,巩固基础

Thread 线程状态

在这里插入图片描述

状态分析

BLOCKED

线程处于阻塞状态
1、等待进去同步块或者代码(synchronized)

2、调用Object.wait之后被唤醒

  • 是Object类的方法,用于线程间通信。
  • 必须在同步块(synchronized)中调用,否则会抛出IllegalMonitorStateException。
  • 调用wait()的线程会释放持有的锁,并进入等待状态,直到其他线程调用同一个对象的notify()或notifyAll()方法,或者被中断。
  • 通常用于条件等待,即线程等待某个条件成立。
synchronized 演示

定义两个线程Worker-1、Worker-2来抢临界资源,Monitor来监控线程的状态。从结果可以看出没有抢到锁的线程的状态就是BLOCKED

volatile:可以保证临界资源的可见性!!!无法保证原子性!!!

package com.gyg.thread.demo1;

public class TestBLOCKED {
    private static volatile boolean running = true;
    private static final Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (running) {
                synchronized (lock) {
                    for (int i = 0; i < 1000; i++) Math.sin(i);
                }
            }
        }, "Worker-1");

        Thread thread2 = new Thread(() -> {
            while (running) {
                synchronized (lock) {
                    for (int i = 0; i < 1000; i++) Math.cos(i);
                }
            }
        }, "Worker-2");

        // 监控线程
        Thread monitor = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
                } catch (Exception e) {
                    break;
                }
            }
        }, "Monitor");
        monitor.start();
        thread1.start();
        thread2.start();
        Thread.sleep(10000);
        running = false;
    }
}

E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=57889” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestBLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: TERMINATED, Worker2 status: TERMINATED

Process finished with exit code 0

Object.wait演示

模拟队列的工作模式,调用wait方法后,线程有RUNNABLE转到WAITING,当调用notifyAll之后,状态由WAITING变为BLOCKED,继续抢临界资源。

package com.gyg.thread.demo1;

import java.util.LinkedList;
import java.util.Queue;

public class TestBLOCKED2 {
    private static volatile boolean running = true;
    private static final Object lock = new Object();
    private static Queue<Integer> queue = new LinkedList<>();
    private static int capacity = 10; // Set a default capacity

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (running) {
                synchronized (lock) {
                    while (queue.size() >= capacity) {
                        try {
                            lock.wait(); // 队列已满,等待
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            throw new RuntimeException(e);
                        }
                    }
                    queue.add(1);
                    lock.notifyAll(); // 唤醒等待的消费者线程
                }
            }
        }, "Worker-1");

        Thread thread2 = new Thread(() -> {
            while (running) {
                synchronized (lock) {
                    while (queue.isEmpty()) {
                        try {
                            lock.wait(); // 队列为空,等待
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            throw new RuntimeException(e);
                        }
                    }
                    queue.remove();
                    lock.notifyAll(); // 唤醒等待的生产者线程
                }
            }
        }, "Worker-2");

        // 监控线程
        Thread monitor = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
                } catch (Exception e) {
                    break;
                }
            }
        }, "Monitor");
        monitor.start();
        thread1.start();
        thread2.start();
        Thread.sleep(10000);
        running = false;
    }
}

E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=57754” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestBLOCKED2
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: RUNNABLE
Worker1 status: BLOCKED, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: TERMINATED, Worker2 status: TERMINATED

Process finished with exit code 0

WAITING

等待状态

1、调用了Object.wait()

2、Thread.join()

3、LockSupport.park

  • Object.wait() 是让当前线程等待并释放锁,直到其他线程通知。
  • Thread.join() 是让当前线程等待另一个线程结束。
Thread.join测试

模拟等待,Worker-2等待Worker-1线程执行完成。从结果来看,调用Thread.join当前线程状态由RUNNABLE变成WAITING当Worker-1结束后,线程状态也会变成 TERMINATED

package com.gyg.thread.demo1;

public class TestWAITING {
    private static volatile boolean running = true;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (running) {
                for (int i = 0; i < 1000; i++) Math.sin(i);
            }
        }, "Worker-1");

        Thread thread2 = new Thread(() -> {
            try {
                thread1.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "Worker-2");

        // 监控线程
        Thread monitor = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
                } catch (Exception e) {
                    break;
                }
            }
        }, "Monitor");
        monitor.start();
        thread1.start();
        thread2.start();
        Thread.sleep(10000);
        running = false;
    }
}

E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=63198” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATED

Process finished with exit code 0

LockSupport演示

从结果可以看出调用LockSupport.park和Object.wait一样状态会变成WAITING,都需要解除等待的状态

LockSupport是JUC的包,基于信号量设计的,unpark可以在park之前,相当于先给你钥匙再给你锁。

package com.gyg.thread.demo1;

import java.util.concurrent.locks.LockSupport;

public class TestWAITING2 {
    private static volatile boolean running = true;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (running) {
                for (int i = 0; i < 1000; i++) Math.sin(i);
            }
        }, "Worker-1");

        Thread thread2 = new Thread(() -> {
            while (running) {
                LockSupport.park();
            }
        }, "Worker-2");

        // 监控线程
        Thread monitor = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
                } catch (Exception e) {
                    break;
                }
            }
        }, "Monitor");
        monitor.start();
        thread1.start();
        thread2.start();
        Thread.sleep(10000);
        running = false;
        LockSupport.unpark(thread2);
    }
}

E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=49846” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING2
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATED

Process finished with exit code 0

TIMED_WAITING

线程处于有时间限制的等待状态

1、Thread.sleep
2、Object.wait 暂停
3、Thread.join 暂停
4、LockSupport.parkNanos
5、LockSupport.parkUntil

这里的方法,入参都可以传递时间参数

LockSupport.parkNanos演示

Worker-1 一直执行,Worker-2等待2S执行,从结果看Worker-2在等待时候的线程状态是 TIMED_WAITING,等待结束会变成RUNNABLE

package com.gyg.thread.demo1;

import java.util.concurrent.locks.LockSupport;

public class TestWAITING2 {
    private static volatile boolean running = true;

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            while (running) {
                for (int i = 0; i < 1000; i++) Math.sin(i);
            }
        }, "Worker-1");

        Thread thread2 = new Thread(() -> {
            while (running) {
                LockSupport.parkNanos(2000000L);
                for (int i = 0; i < 1000; i++) Math.cos(i);
            }
        }, "Worker-2");

        // 监控线程
        Thread monitor = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(1000);
                    System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
                } catch (Exception e) {
                    break;
                }
            }
        }, "Monitor");
        monitor.start();
        thread1.start();
        thread2.start();
        Thread.sleep(10000);
        running = false;
        LockSupport.unpark(thread2);
    }
}

E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=55839” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING2
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATED

Process finished with exit code 0

尾声

如果解决有解决你的问题,点点赞,求个关注👍👍👍
醉后不知天在水,满船清梦压星河🤞🤞🤞,加油👏👏👏

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐