某面试题,实现一个生产者——消费者模型
题目:采用多线程技术,通过wait/notify,设计实现一个符合生产者和消费者问题的程序,对某一个对象(枪膛)进行操作,其最大容量是20颗子弹,生产者线程是一个压入线程,它不断向枪膛中压入子弹,消费者线程是一个射出线程,它不断从枪膛中射出子弹。
public class Test {
public Queue<Integer> gun = new LinkedList<Integer>(); // 枪
public final int maxCount = 20; // 枪里面最多上20发子弹
public final int maxbulletCount = 200; // 枪里面最多上20发子弹
public final int[] bullets = new int[maxbulletCount];
private int pos = 0;
public Test() {
Random r = new Random();
for (int i = 0; i < maxbulletCount; i++) {
bullets[i] = r.nextInt(1000);
}
}
private int getBullet() {
return pos < maxbulletCount ? bullets[pos++] : -1;
}
class Producer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (gun) {
try {
if(gun.size() == maxCount){
System.out.println("*********** 枪膛已经上满子弹");
gun.wait();
} else {
int i = getBullet();
if (i == -1) {
System.out.println("*********** 子弹已经用完");
Thread.interrupted();
} else {
gun.add(i);
System.out.println("*********** 子弹" + i + "上膛 枪里面还有" + gun.size() + "颗子弹");
try {
Thread.sleep(199);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
gun.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Consumer implements Runnable {
public void run() {
while (true) {
synchronized (gun) {
try {
if( gun.size() == 0 ){
System.out.println("*********** 枪没子弹了 ");
gun.wait();
} else {
Integer bullet = gun.poll();
System.out.println("*********** 使用子弹" + bullet + ", 枪里面还有" + gun.size() + "颗子弹");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
gun.notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Test t = new Test();
Thread p = new Thread(t.new Producer());
Thread c = new Thread(t.new Consumer());
p.start();
c.start();
}
}
值得注意的是:notify并不释放锁,只是唤醒其他线程来竞争锁,当synchronized代码执行完才释放锁。一般建议使用notifyAll,不使用notify,因为notify容器造成信号丢失,并不一定能通知到我们想要告知的线程。
来源:oschina
链接:https://my.oschina.net/u/4402731/blog/3567786