java.util.concurrent中的线程无法停止和虚假唤醒问题
package thread.juc;
public class TestProductAndConsumer {
public static void main(String[] args) {
// crtl +shift+o 导包
Clerk clerk = new Clerk();
Consumer consumer= new Consumer(clerk);
Product product = new Product(clerk);
new Thread(product,"A").start();
new Thread(consumer,"B").start();
new Thread(product,"C").start();
new Thread(consumer,"D").start();
}
}
class Clerk{
private int product = 0;
// 进货
public synchronized void get(){//loop2
while (product>=1){
System.out.println("库存已满");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//将else 去掉 线程多操作几次 解决其中一个线程停不下来 结束不了的问题
System.out.println("生产者"+Thread.currentThread().getName()+"\t"+ ++product);
this.notifyAll();
/*else {
System.out.println("生产者"+Thread.currentThread().getName()+"\t"+ ++product);
this.notifyAll();
}*/
}
public synchronized void sale(){ //product 0 loop1
while (product<=0){ // 将if 改为while 解决虚假唤醒 如果使用if product<0 当两个消费者线程同时进入 wait 当生产者线程唤醒 --两次
System.out.println("缺货!!!");
try {
this.wait(); //等在这位置 同时释放锁资源 --->当product=0 loop=0 跳出当前循环 生产者product=1 库存已满 consumer循环次数=0 无法唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者"+Thread.currentThread().getName()+"\t"+ --product);
this.notifyAll();
}
}
class Product implements Runnable{
private Clerk clerk;
public Product(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
clerk.get();
}
}
}
class Consumer implements Runnable{
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
clerk.sale();
}
}
}
/*
class Clerk{
private int product = 0;
// 进货
public synchronized void get(){//loop2
if (product>=1){
System.out.println("库存已满");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
System.out.println("生产者"+Thread.currentThread().getName()+"\t"+ ++product);
this.notifyAll();
}
}
public synchronized void sale(){ //product 0 loop1
if (product<=0){
System.out.println("缺货!!!");
try {
this.wait(); //等在这位置 同时释放锁资源 --->当product=0 loop=0 跳出当前循环 生产者product=1 库存已满 consumer循环次数=0 无法唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
System.out.println("消费者"+Thread.currentThread().getName()+"\t"+ --product);
this.notifyAll();
}
}
}
class Product implements Runnable{
private Clerk clerk;
public Product(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
clerk.get();
}
}
}
class Consumer implements Runnable{
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
clerk.sale();
}
}
}*/