文章目录
threadStatus线程状态
private volatile int threadStatus;
线程状态一般有以下值
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
状态图
源码解析及例子
BLOCKED
源码解析
public enum State {
// other source codes...
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
如果线程处于BLOCKED状态,它正在等待获得一个监视器锁为了能够
1. 进入一个synchronized修饰的代码块或者方法
2. 在调用Object.wait()方法后重新进入synchronized修饰的代码块或者方法
*/
BLOCKED,
// other source codes...
}
第一次enter例子
先看例子的流程图
代码实现
public class Enter {
public static void main(String[] args) throws InterruptedException {
// 创建计算器实例
Counter counter = new Counter();
// 开启线程1
Thread thread1 = new Thread("线程1") {
@Override
public void run() {
counter.increase();
}
};
thread1.start();
Thread.sleep(100); // 确保thread1得到执行
// 开启线程2
Thread thread2 = new Thread("线程2") {
@Override
public void run() {
counter.increase();
}
};
thread2.start();
Thread.sleep(100); // 确保thread2得到执行
System.out.println("State of thread2: " + thread2.getState());
}
}
// 创建计算器类
class Counter{
private int count = 0;
public synchronized void increase() {
System.out.println(Thread.currentThread().getName() + " starts counting!!!");
try {
count++;
Thread.sleep(1000); // 线程1执行后阻塞,使得线程2可以进入BLOCKED状态
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ends counting!!!");
}
}
执行代码后结果
线程1 starts counting!!!
State of thread2: BLOCKED
线程1 ends counting!!!
线程2 starts counting!!!
线程2 ends counting!!!
在线程1结束之前线程2被阻塞,状态为BLOCKED
reenter例子
例子的流程图
代码实现
public class Reenter {
public static void main(String[] args) throws InterruptedException {
// 创建Account实例
Account account = new Account();
// 开启取钱线程
Thread thread1 = new Thread("取钱线程") {
@Override
public void run() {
account.take(50);
}
};
thread1.start();
Thread.sleep(100); // 确保取钱线程得到执行
System.out.println("State of " + thread1.getName() + ": " + thread1.getState());
// 开启存钱线程
Thread thread2 = new Thread("存钱线程") {
@Override
public void run() {
account.store(100);
}
};
thread2.start();
Thread.sleep(100); // 确保存钱线程得到执行
System.out.println("State of " + thread1.getName() + ": " + thread1.getState());
}
}
// 定义账户类,该类有money变量记录当前有多少钱; store方法表示存钱;take方法表示取钱
class Account{
private int money = 0;
// 存钱
public synchronized void store(int storeCash) {
System.out.println(Thread.currentThread().getName() + "-存钱 starts!!!");
money += storeCash;
notify();
try {
Thread.sleep(1000); // 通知后暂时不退出,使取钱线程进入blocked状态
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName() + "-存钱 ends!!!");
}
// 取钱
public synchronized void take(int takeCash) {
System.out.println(Thread.currentThread().getName() + "-取钱 starts!!!");
// 钱不够的时候阻塞
while (takeCash > money) {
try {
wait();
} catch (Exception e) {
}
}
money -=takeCash;
System.out.println(Thread.currentThread().getName() + "-取钱 ends!!!");
}
}
运行后结果
取钱线程-取钱 starts!!!
State of 取钱线程: WAITING
存钱线程-存钱 starts!!!
State of 取钱线程: BLOCKED
存钱线程-存钱 ends!!!
取钱线程-取钱 ends!!!
WAITING
源码解析
public enum State {
// other source codes...
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
* 当调用了下面其中一个方法后,线程会进入WAITING状态
* 1. Object.wait()不带参数
2. Thread.join()不带参数
3. LockSupport.park()
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
处于WAITING状态的线程在等待另一个线程执行某些特殊操作后才能改变状态
*
* For example, a thread that has called {@code Object.wait()}
* on an object is waiting for another thread to call
* {@code Object.notify()} or {@code Object.notifyAll()} on
* that object. A thread that has called {@code Thread.join()}
* is waiting for a specified thread to terminate.
比如说
1. 如果调用了Object.wait(),需要另一个线程调用Object.notify()或者Object.notifyAll()
2. 如果调用了Thread.join(),需要另一个线程终止才能退出该状态
*/
WAITING,
// other source codes...
}
例子解析
wait
public class Wait {
public static void main(String[] args) throws InterruptedException {
// 创建等待类实例
WaitClazz waitClazz = new WaitClazz();
// 创建等待线程1
Thread thread1 = new Thread("thread-1") {
@Override
public void run() {
waitClazz.waitTest();
}
};
thread1.start();
Thread.sleep(100); // 确保线程1执行
System.out.println("State of " + thread1.getName() + " is " + thread1.getState());
// 唤醒单个等待线程
Thread thread2 = new Thread("thread-2") {
@Override
public void run() {
waitClazz.notifyTest();
}
};
thread2.start();
Thread.sleep(100); // 确保线程2执行
System.out.println("State of " + thread1.getName() + " is " + thread1.getState());
Thread.sleep(5000);
System.out.println("-------------------------------------");
// 创建等待线程3
Thread thread3 = new Thread("thread-3") {
@Override
public void run() {
waitClazz.waitTest();
}
};
thread3.start();
Thread.sleep(100); // 确保线程3执行
System.out.println("State of " + thread3.getName() + " is " + thread3.getState());
// 创建等待线程4
Thread thread4 = new Thread("thread-4") {
@Override
public void run() {
waitClazz.waitTest();
}
};
thread4.start();
Thread.sleep(100); // 确保线程4执行
System.out.println("State of " + thread4.getName() + " is " + thread4.getState());
// 唤醒所有线程
Thread thread5 = new Thread("thread-5") {
@Override
public void run() {
waitClazz.notifyAllTest();
}
};
thread5.start();
Thread.sleep(100); // 确保线程5执行
System.out.println("State of " + thread3.getName() + " is " + thread3.getState());
System.out.println("State of " + thread4.getName() + " is " + thread4.getState());
}
}
// 创建等待类
class WaitClazz {
// 等待
public synchronized void waitTest() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 唤醒单个线程
public synchronized void notifyTest() {
notify();
System.out.println(Thread.currentThread().getName() + " notify.");
}
// 唤醒所有线程
public synchronized void notifyAllTest() {
notifyAll();
System.out.println(Thread.currentThread().getName() + " notifyAll.");
}
}
运行后结果
State of thread-1 is WAITING
thread-2 notify.
State of thread-1 is TERMINATED
-------------------------------------
State of thread-3 is WAITING
State of thread-4 is WAITING
thread-5 notifyAll.
State of thread-3 is TERMINATED
State of thread-4 is TERMINATED
join
public static void main(String[] args) throws InterruptedException {
Thread parent = Thread.currentThread();
Thread subThread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 500000; i++) {
}
System.out.println("Inner->Main线程状态: " + parent.getState());
System.out.println("子线程结束");
}
};
subThread.start();
subThread.join();
System.out.println("Outer->Main线程状态: " + parent.getState());
}
结果
Inner->Main线程状态: WAITING
子线程结束
Outer->Main线程状态: RUNNABLE
当subThread调用join方法后会阻塞Main线程,直到它自己执行完毕才会继续往下走。为了更清楚了解我们看下在没有调用join方法下的结果
public static void main(String[] args) throws InterruptedException {
Thread parent = Thread.currentThread();
Thread subThread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 500000; i++) {
}
System.out.println("Inner->Main线程状态: " + parent.getState());
System.out.println("子线程结束");
}
};
subThread.start();
// subThread.join();
System.out.println("Outer->Main线程状态: " + parent.getState());
}
结果
Outer->Main线程状态: RUNNABLE
Inner->Main线程状态: TERMINATED
子线程结束
子线程不阻塞Main线程,在执行子线程run时主线程已经终止了
park
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
System.out.println("State before park: " + Thread.currentThread().getState());
LockSupport.park();
});
thread.start();
Thread.sleep(1000);
System.out.println("State before unpark: " + thread.getState());
LockSupport.unpark(thread);
}
结果
State before park: RUNNABLE
State before unpark: WAITING
TIMED_WAITING
源码解析
public enum State {
// other source codes...
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
// other source codes...
}
sleep
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println("State after sleep: " + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("State after created: " + thread.getState());
thread.start();
System.out.println("State after start: " + thread.getState());
Thread.sleep(500); // 确保线程进入休眠状态
System.out.println("State when sleeping: " + thread.getState());
Thread.sleep(5000); // 确保线程退出
System.out.println("State after executed: " + thread.getState());
}
结果
State after created: NEW
State after start: RUNNABLE
State when sleeping: TIMED_WAITING
State after sleep: RUNNABLE
State after executed: TERMINATED
wait
public static void main(String[] args) throws InterruptedException {
class WaitClazz {
public synchronized void waitTest(long millSeconds) throws InterruptedException {
wait(1000);
}
}
WaitClazz waitClazz = new WaitClazz();
Thread thread = new Thread(() -> {
try {
waitClazz.waitTest(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("State after created: " + thread.getState());
thread.start();
System.out.println("State after start: " + thread.getState());
Thread.sleep(500); // 确保线程进入等待
System.out.println("State after sleep: " + thread.getState());
}
结果
State after created: NEW
State after start: RUNNABLE
State after sleep: TIMED_WAITING
join
public static void main(String[] args) throws InterruptedException {
Thread parent = Thread.currentThread();
Thread subThread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 50000; i++) {
}
System.out.println("Inner->Main线程状态: " + parent.getState());
System.out.println("线程结束循环");
}
};
subThread.start();
subThread.join(1000);
}
结果
Inner->Main线程状态: TIMED_WAITING
线程结束循环
parkNanos
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
System.out.println("State before parkNanos: " + Thread.currentThread().getState());
LockSupport.parkNanos(10 * 1000 * 1000 * 1000);
System.out.println("State after parkNanos: " + Thread.currentThread().getState());
});
thread.start();
Thread.sleep(500);
System.out.println("State before park timeout: " + thread.getState());
}
结果
State before parkNanos: RUNNABLE
State before park timeout: TIMED_WAITING
State after parkNanos: RUNNABLE
parkUntil
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
System.out.println("State before parkNanos: " + Thread.currentThread().getState());
LockSupport.parkUntil(System.currentTimeMillis() + 1000);
System.out.println("State after parkNanos: " + Thread.currentThread().getState());
});
thread.start();
Thread.sleep(500);
System.out.println("State before park timeout: " + thread.getState());
}
结果
State before parkNanos: RUNNABLE
State before park timeout: TIMED_WAITING
State after parkNanos: RUNNABLE