生产者与消费者问题,在计算机操作系统有详细的说明,但是书中使用的是信号量解决的。其实Java也有相似的方案解决这个问题。
public class CPTest {
private static int in = 0;
private static int out = 0;
private static int[] buffer = new int[5];
private static Semaphore mutex = new Semaphore(1);
private static Semaphore empty = new Semaphore(5);
private static Semaphore full = new Semaphore(0);
static class Procedure implements Runnable {
@Override
public void run() {
while (true) {
try {
empty.acquire();
mutex.acquire();
buffer[in] = 1;
in = (in + 1) % 5;
System.out.println(Thread.currentThread().getName());
System.out.println("生产了" + in + "个面包");
Thread.sleep(((int)Math.random())%10);
} catch (Exception e) {
e.printStackTrace();
} finally {
mutex.release();
full.release();
}
}
}
}
static class Consumer implements Runnable {
@Override
public void run() {
while (true) {
try {
full.acquire();
mutex.acquire();
buffer[out] = 0;
out = (out + 1) % 5;
System.out.println(Thread.currentThread().getName());
System.out.println("消费了" + out + "个面包");
Thread.sleep(((int)Math.random())%10);
} catch (Exception e) {
e.printStackTrace();
} finally {
mutex.release();
empty.release();
}
}
}
}
public static void main(String[] args) {
new Thread(new Procedure(), "A").start();
new Thread(new Consumer(), "B").start();
}
}
其实,常用的wait-notify方案,但是要注意虚假唤醒,不能使用if,建议使用while
public class CPTest2 {
private static int MAX_COUNT = 10;
private static String LOOK = "look";
private static int count = 0;
private static List<Integer> list = new ArrayList<>();
static class Procedure implements Runnable {
@Override
public void run() {
while (true) {
synchronized (LOOK) {
while (list.size() == MAX_COUNT) {
try {
System.out.println(Thread.currentThread().getName());
System.out.println("list is full, waiting...");
LOOK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
list.add(count);
System.out.println(Thread.currentThread().getName());
System.out.println("生产了" + list.size() + "个面包");
LOOK.notifyAll();
}
}
}
}
static class Consumer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (LOOK) {
while (list.size() == 0) {
try {
System.out.println(Thread.currentThread().getName());
System.out.println("list is empty, waiting...");
LOOK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer integer = list.get(0);
list.remove(0);
System.out.println(Thread.currentThread().getName());
System.out.println("消费了一个,剩余" + list.size() + "个面包");
LOOK.notifyAll();
}
}
}
}
public static void main(String[] args) {
new Thread(new Procedure(), "a1").start();
new Thread(new Consumer(), "a11").start();
}
}
网友评论