一个奶箱类
package com.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class box {
private int milk;
private boolean state=false;
Lock lock=new ReentrantLock();
/* public void getMilk(int milk) {
this.milk-=milk;
System.out.println("剩余牛奶:"+this.milk);
}
public void setMilk(int milk) {
this.milk += milk;
System.out.println("剩余牛奶:"+this.milk);
}*/
public synchronized void getMilk() {
if(!state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ":" + this.milk);
notifyAll();
state = false;
}
public synchronized void setMilk(int milk) {
if(state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有牛奶,生产牛奶
this.milk = milk;
System.out.println(Thread.currentThread().getName()+":"+this.milk);
state=true;
notifyAll();
}
}
一个生产者类
package com.test;
public class product implements Runnable{
private box box;
public product(box b){
this.box=b;
}
@Override
public void run() {
for(int i=1;i<=30;i++) {
box.setMilk(i);
}
}
}
一个消费者类
package com.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class sell implements Runnable{
private box box;
private int num=0;
public sell(box b) {
this.box=b;
}
@Override
public void run() {
while(true){
box.getMilk();
}
}
}
测试类,创建一个生产者线程。两个线程构造传入同一消费者对象;
package com.test;
import java.awt.*;
import java.io.*;
import java.nio.BufferUnderflowException;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
box bo=new box();
sell s=new sell(bo);
product p=new product(bo);
Thread t1=new Thread(p,"生产者");
Thread t2=new Thread(s,"消费者");
Thread t3=new Thread(s,"消费者2");
t1.start();
t2.start();
t3.start();
}
}
预期结果:
生产一瓶奶
两个消费者争抢
最终只有一人喝到
产生问题:
最终解决:给奶箱类里的获取牛奶方法加了else
public synchronized void getMilk() {
if(!state){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
System.out.println(Thread.currentThread().getName() + ":" + this.milk);
notifyAll();
state = false;
}
}
效果:
疑惑:为啥synchronized 锁没起作用,按理说两个消费者只能进一个,,
刚开始怎么会出错,最终的解决也莫名其妙。跟else写不写没关吧,一个消费者进入这个同步方法不就锁起来了吗,如果state为true,那自然不会执行if里的判断,直接顺序执行