/**
- 线程通信
- 三种方式: 【suspend/resume、wait/notify、park/unpark】
- suspend/resume:java废弃的方法【原因:加同步锁容易造成死锁;先后顺序弄反容易导致线程无线挂起】
- wait/notify:线程,睡眠\唤醒 【先后顺序弄反容易造成线程无线挂起】
- park/unpark:线程 挂起\释放 【加同步锁容易造成死锁】
*/
代码如下:
package com.nipeixing.demo.thread;
import java.util.concurrent.locks.LockSupport;
public class ThreadSignaling {
//包子店
private static Object baozi = null;
//region suspend/resume详解
//正常的suspend/resume
public void suspendTest() throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
Thread.currentThread().suspend();
}
System.out.println("2、买到包子,回家");
}
});
thread1.start();
Thread.sleep(3000L);
baozi = new Object();
thread1.resume();
System.out.println("3、生产出包子");
}
//死锁的suspend/resume
public void suspendTest1() throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
synchronized (ThreadSignaling.class) {
Thread.currentThread().suspend();
}
}
System.out.println("2、买到包子,回家");
}
});
thread1.start();
Thread.sleep(3000L);
baozi = new Object();
synchronized (ThreadSignaling.class) {
thread1.resume();
}
System.out.println("3、生产出包子");
}
// 无限挂起,先后顺序乱了,消费者没有出发生产,但是生产者已经生产,无法通知消费者
public void suspendTest2() throws InterruptedException {
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.currentThread().suspend();
}
System.out.println("2、买到包子,回家");
}
});
thread3.start();
Thread.sleep(3000L);
baozi = new Object();
thread3.resume();
System.out.println("3、生产出包子");
}
//endregion
//region wait/notify 详解
/**
* wait/notify 一定要在同步代码块中使用
* 正常的操作
*/
public void waitTest() throws InterruptedException {
new Thread(() -> {
while (baozi == null) {
synchronized (this) {
System.out.println("1、没有包子,进入等待");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("2、买到包子,回家");
}).start();
Thread.sleep(3000L);
baozi = new Object();
synchronized (this) {
System.out.println("3、生产出包子");
this.notify();
}
}
/**
* wait/notify 一定要在同步代码块中使用
* 会导致线程永远挂起的操作
*/
public void waitTest1() throws Exception {
new Thread(() -> {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
try {
Thread.sleep(6000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("2、买到包子,回家");
}).start();
Thread.sleep(3000L);
baozi = new Object();
synchronized (this) {
System.out.println("3、生产出包子");
this.notify();
}
}
//endregion
//region park/unpark 详解
/**
* 正常操作
*/
public void parkTest() throws InterruptedException {
Thread thread4 = new Thread(() -> {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
LockSupport.park();
}
System.out.println("2、买到包子,回家");
});
thread4.start();
Thread.sleep(3000L);
baozi = new Object();
System.out.println("3、生产出包子");
LockSupport.unpark(thread4);
}
/**
* 死锁操作
*/
public void parkTest1() throws InterruptedException {
Thread thread4 = new Thread(() -> {
while (baozi == null) {
System.out.println("1、没有包子,进入等待");
synchronized (this) {
LockSupport.park();
}
}
System.out.println("2、买到包子,回家");
});
thread4.start();
Thread.sleep(3000L);
baozi = new Object();
synchronized (this) {
System.out.println("3、生产出包子");
LockSupport.unpark(thread4);
}
}
//endregion
public static void main(String[] args) throws Exception {
//new ThreadSignaling().suspendTest();
//new ThreadSignaling().suspendTest1();
// new ThreadSignaling().suspendTest2();
//new ThreadSignaling().waitTest();
//new ThreadSignaling().waitTest1();
//new ThreadSignaling().parkTest();
new ThreadSignaling().parkTest1();
}
}