1、生产者与消费者模式(传统锁实现)
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PCtradiotonal {
public static void main(String[] args) {
Sharedata sharedata=new Sharedata();
new Thread(()->{
for (int i = 1; i <5; i++) {
try {
sharedata.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"生产者生产") .start();
new Thread(()->{
for (int i = 1; i <5; i++) {
try {
sharedata.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"消费者消费") .start();
}
}
class Sharedata{
private int num=0;
private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
public void increment() throws InterruptedException {
lock.lock();
try {
while (num!=0) {
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName()+" "+num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void decrement() throws InterruptedException {
lock.lock();
try {
while (num==0) {
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName()+" "+num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
利用num的值进行线程间的交换,num=0即生产者生产,num=1即消费者消费
2、生产者与消费者模式(阻塞队列实现)
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class PCBlockingQ {
public static void main(String[] args) {
MyRescourse myRescourse=new MyRescourse(new ArrayBlockingQueue<>(10));
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"生产线程启动");
try {
myRescourse.myProd();
} catch (Exception e) {
e.printStackTrace();
}
},"Product").start();
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"消费线程启动");
try {
myRescourse.myCust();;
} catch (Exception e) {
e.printStackTrace();
}
},"Customer").start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
System.out.println();
System.out.println("5s到");
myRescourse.stop();
}
}
class MyRescourse{
private volatile boolean FLAG=true;
private AtomicInteger atomicInteger=new AtomicInteger();
BlockingQueue<String> blockingQueue=null;
public MyRescourse(BlockingQueue<String> blockingQueue) {
this.blockingQueue=blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}
public void myProd() throws Exception {
String data=null;
boolean reValue;
while (FLAG) {
data=atomicInteger.incrementAndGet()+"";
reValue=blockingQueue.offer(data,1,TimeUnit.SECONDS);
if (reValue) {
System.out.println(Thread.currentThread().getName()+" 插入队列"+data+"成功");
}else {
System.out.println(Thread.currentThread().getName()+" 插入队列"+data+"失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println("生产结束");
}
public void myCust() throws Exception {
String res=null;
while (FLAG) {
res=blockingQueue.poll(2, TimeUnit.SECONDS);
if (null==res||res.equalsIgnoreCase("")) {
FLAG=false;
System.out.println(Thread.currentThread().getName()+"超过两秒,消费退出");
}
System.out.println(Thread.currentThread().getName()+" 消费队列"+res+"成功");
}
}
public void stop() {
this.FLAG=false;
}
}
阻塞队列的底层其实也是用reentrantlock实现的。