我已经通过几种方式解决了P / C问题。任何人都可以检查它们的正确性吗? 提前谢谢。
1)的BlockingQueue
public static void main(String[] args) {
BlockingQueue<Object> blockingQueue = new LinkedBlockingQueue<Object>(10);
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
class Producer implements Runnable {
private BlockingQueue<Object> blockingQueue;
private Random random = new Random();
public Producer(BlockingQueue<Object> blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.put(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private BlockingQueue<Object> blockingQueue;
private Random random = new Random();
public Consumer(BlockingQueue<Object> blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2)锁
public static void main(String[] args) {
CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
private static final int MAX_SIZE = 10;
private static final Lock lock = new ReentrantLock();
private static final Condition fullState = lock.newCondition();
private static final Condition emptyState = lock.newCondition();
@Override
public boolean offer(Object e) {
boolean result;
lock.lock();
try {
if (size() >= MAX_SIZE) {
try {
fullState.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
result = super.offer(e);
System.out.println("offer " + size());
emptyState.signal();
} finally {
lock.unlock();
}
return result;
}
@Override
public Object poll() {
Object result;
lock.lock();
try {
if (size() == 0) {
try {
emptyState.await();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
}
result = super.poll();
System.out.println("poll " + size());
fullState.signal();
} finally {
lock.unlock();
}
return result;
}
}
class Producer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Producer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.offer(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Consumer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3-4)显示器
public static void main(String[] args) {
CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
private static final int MAX_SIZE = 10;
@Override
public synchronized boolean offer(Object e) {
if (size() >= MAX_SIZE) {
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
boolean result = super.offer(e);
System.out.println("offer " + size());
notify();
return result;
}
@Override
public synchronized Object poll() {
if (size() == 0) {
try {
wait();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
}
Object result = super.poll();
System.out.println("poll " + size());
notify();
return result;
}
}
class Producer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Producer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.offer(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Consumer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
和
public static void main(String[] args) {
CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
private static final int MAX_SIZE = 10;
private static final Object fullLock = new Object();
private static final Object emptyLock = new Object();
@Override
public boolean offer(Object e) {
synchronized (fullLock) {
if (size() >= MAX_SIZE) {
try {
fullLock.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
synchronized (emptyLock) {
boolean result = super.offer(e);
System.out.println("offer " + size());
emptyLock.notify();
return result;
}
}
@Override
public Object poll() {
synchronized (emptyLock) {
if (size() == 0) {
try {
emptyLock.wait();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
}
}
synchronized (fullLock) {
Object result = super.poll();
System.out.println("poll " + size());
fullLock.notify();
return result;
}
}
}
class Producer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Producer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.offer(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Consumer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者生产者问题(也称为有界缓冲问题)是多进程同步问题的典型示例。该问题描述了两个进程,生产者和使用者,他们共享一个用作队列的通用固定大小缓冲区。制作人的工作是生成一段数据,将其放入缓冲区并重新开始。同时,消费者一次一件地消费数据(即,将其从缓冲器中移除)。问题是确保生产者不会尝试将数据添加到缓冲区中,如果它已满并且消费者不会尝试从空缓冲区中删除数据。
如果缓冲区已满,生产者的解决方案是进入睡眠状态或丢弃数据。消费者下次从缓冲区中删除项目时,它会通知生产者,生产者再次开始填充缓冲区。以同样的方式,如果消费者发现缓冲区为空,则消费者可以进入睡眠状态。下一次生产者将数据放入缓冲区时,它会唤醒沉睡的消费者。可以通过进程间通信来访问解决方案,通常使用信号量。解决方案不充分可能导致两个进程等待唤醒的死锁。这个问题也可以推广到拥有多个生产者和消费者。