例子:
生产者: 往一个公共的盒子里面放苹果
消费者:从公共的盒子里面取苹果
盒子:盒子的容量不能超过10
方法一:
Producer.java:
public class Producer extends Thread{
private Test test;
public Producer(Test obj){
this.test= obj;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
System.out.println("pro i = " + i);
test.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Consumer.java:
public class Consumer extends Thread{
private Test test;
public Consumer(Test obj){
this.test= obj;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(3000);
System.out.println("Con i =" + i);
test.decrease();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
producer 和 consumer是两个线程,分别扮演着生产者和消费者,共享Test类的资源。
Test.java:
public class Test {
public int count = 0;
public synchronized void increase() throws InterruptedException {
while(count == 10){
wait();
}
count ++;
System.out.println("生产了一个苹果,现在count:" + count);
notify();
}
public synchronized void decrease() throws InterruptedException {
while(count == 0){
wait();
}
count --;
System.out.println("消费了一个苹果,现在count:" + count);
notify();
}
public static void main(String[] args) {
Test test = new Test();
Thread consumer = new Consumer(test);
Thread producer = new Producer(test);
consumer.start();
producer.start();
}
}
运行结果:
pro i = 0
生产了一个苹果,现在count:1
pro i = 1
生产了一个苹果,现在count:2
Con i =0
消费了一个苹果,现在count:1
pro i = 2
生产了一个苹果,现在count:2
pro i = 3
生产了一个苹果,现在count:3
pro i = 4
生产了一个苹果,现在count:4
Con i =1
消费了一个苹果,现在count:3
pro i = 5
生产了一个苹果,现在count:4
pro i = 6
生产了一个苹果,现在count:5
pro i = 7
生产了一个苹果,现在count:6
Con i =2
消费了一个苹果,现在count:5
pro i = 8
生产了一个苹果,现在count:6
pro i = 9
生产了一个苹果,现在count:7
Con i =3
消费了一个苹果,现在count:6
Con i =4
消费了一个苹果,现在count:5
Con i =5
消费了一个苹果,现在count:4
Con i =6
消费了一个苹果,现在count:3
Con i =7
消费了一个苹果,现在count:2
Con i =8
消费了一个苹果,现在count:1
Con i =9
方法2:
使用阻塞队列,它是一个FIFO及先进先出的阻塞队列,提供了阻塞的 pu t和 take 方法:
ProducerQueue.java:
public class ProducerQueue extends Thread{
private BlockingQueue<Integer> blockingQueue;
public ProducerQueue(BlockingQueue blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
blockingQueue.put(i);
System.out.println("生产了: " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ConsumerQueue.java:
public class ConsumerQueue extends Thread{
private BlockingQueue<Integer> blockingQueue;
public ConsumerQueue(BlockingQueue blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(3000);
System.out.println("消费了,值为:" + blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
TestQueue.java:
public class TestQueue {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);
Thread consumer = new ConsumerQueue(queue);
Thread producer = new ProducerQueue(queue);
consumer.start();
producer.start();
}
}
结果:
生产了: 0
生产了: 1
消费了,值为:0
生产了: 2
生产了: 3
生产了: 4
消费了,值为:1
生产了: 5
生产了: 6
消费了,值为:2
生产了: 7
消费了,值为:3
生产了: 8
消费了,值为:4
生产了: 9
消费了,值为:5
消费了,值为:6
消费了,值为:7
消费了,值为:8
消费了,值为:9