1,使用阻塞队列blockingqueue实现简单的生产者消费者模型
原理:阻塞队列BlockingQueue本身就是线程安全,同时使用阻塞队列提供的take,put方法在操作阻塞队列会是使得队列进入阻塞。因此阻塞队列就是线程安全的。基于阻塞队列以上的性质就可以实现线程安全的生产者消费者模型。
代码如下:
package 比较器java特性;
// 此代码中使用了Lambda表达式来作为参数完成进程的我创建
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
public class BlockingQueuePC {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> blockingqueue=new LinkedBlockingQueue<>(2);
CountDownLatch cd = new CountDownLatch(2);
Thread t1 = new Thread(()->{
try {
for(int i=0;i<10;i++)
{
blockingqueue.put("goods"+i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
cd.countDown();
}
});
Thread t2 = new Thread(()->{
try {
for(int i=0;i<10;i++)
{
System.out.println(blockingqueue.take());
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
cd.countDown();
}
});
t2.start();
t1.start();
cd.await();
System.out.println(blockingqueue.size());
}
}
2, 使用信号量Semaphore来实现生产者消费者同步访问资源问题
原理:根据操作系统的信号量来对临界资源进行同步访问,本问题主要有三个临界资源分别就是full(当前的容量或者说产品数量),empty(表示当前的容器的空闲容量),mutex(这个就比较简单表示读写锁,并且一个时刻只允许一个线程进行访问)。只要控制 好对这三个临界资源的访问就可以实现生产者消费者模式模型。
代码如下:
package 比较器java特性;
import java.util.*;
import java.util.concurrent.Semaphore;
public class SemaphorePC {
// N是容量
private final static int N=10;
// full是容量,empty是空闲容量,mutex是读写锁
private static Semaphore full,empty,mutex;
// 记录当前产品的数量
private static volatile int count=0;
static {
// 开始容量初始化有0个产品
full = new Semaphore(0);
// 开始剩余容量为N
empty = new Semaphore(N);
// 设置只有一个线程获取读写锁
mutex = new Semaphore(1);
}
public static void main(String[] args) {
// 生产者先生产产品
new Thread(new Producer()).start();
// 消费者消费产品
new Thread(new Consumer()).start();
}
public static class Producer implements Runnable{
@Override
public void run() {
while(true) {
try {
empty.acquire();
mutex.acquire();
count++;
System.out.println("生产者生产了一个产品,现在有"+count+"产品");
mutex.release();
full.release();
Thread.sleep((int)Math.random()%10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者主体代码
public static class Consumer implements Runnable{
@Override
public void run() {
try {
full.acquire();
mutex.acquire();
count--;
System.out.println("消费者消费了一个产品,目前还剩下"+count+"个产品");
mutex.release();
empty.release();
Thread.sleep((int)Math.random()%10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}