一个练习串一串最近所学知识。
生产者消费者问题,之前用lock写过,但是阻塞队列的出现,使得我们不需要自己去写它的判断条件,而是初始化阻塞队列之后,他就自己控制存进取出了。
因为是多线程,所以不可避免的,我们的需要volatile关键字,来保持定义变量的可见性,并且还需要用原子整型 AtomicInteger来保证原子性,这样才能保证它在多线程下不出现线程安全问题。
还需要注意的是,这里的阻塞队列我们用ArrayBlockingQueue,LinkedBlockingQueue还是其他的?我们发现如果我们只是将BlockingQueue作为有参构造函数的参数时,所有类型的阻塞队列,都可以在main函数中,被随意传入,所以我们以后得学会将口足够大,使得代码写的更为便利。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class PCBlockingqueue {
private AtomicInteger atomicInteger =new AtomicInteger(0);
BlockingQueue<String> blockingQueue=null;
private static volatile boolean FLAG =true;
public PCBlockingqueue(BlockingQueue blockingQueue){
this.blockingQueue =blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}
public void MyProdo() throws InterruptedException {
String data=null;
boolean result;
while (FLAG){
data = atomicInteger.incrementAndGet()+"";
result =blockingQueue.offer(data,2, TimeUnit.SECONDS);
if (result){
System.out.println(Thread.currentThread().getName()+"成功生产"+data);
}else {
System.out.println(Thread.currentThread().getName()+"生产失败"+data);
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName()+"说boss 破产了,公司倒闭了");
}
public void MyCustom() throws Exception {
String data;
while (FLAG) {
data = blockingQueue.poll(2, TimeUnit.SECONDS);
if (data == null || data.equalsIgnoreCase("")) {
FLAG = false;
System.out.println(Thread.currentThread().getName() + "两秒后,仍然没有生产好的产品,无法消费,消费退出");
return;
}
System.out.println(Thread.currentThread().getName() + "消费成功,消费了编号为" + data + "的产品");
}
}
public void boss(){
this.FLAG=false;
}
public static void main(String[] args) throws Exception {
BlockingQueue blockingQueue =new ArrayBlockingQueue(3);
PCBlockingqueue pcBlockingqueue=new PCBlockingqueue(blockingQueue);
new Thread(()->{
try {
pcBlockingqueue.MyProdo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "产家 " ).start();
new Thread(()->{
try {
pcBlockingqueue.MyCustom();
} catch (Exception e) {
e.printStackTrace();
}
},"吃货 " ).start();
TimeUnit.SECONDS.sleep(5);
new Thread(()->{
pcBlockingqueue.boss();
}, "boss ").start();
}
}