可直接复制后测试
主要思想是想利用BlockingQueue源码中提供的思路去实现手动控制生产者生产动作和消费者的消费动作
实现中利用了SynchronousQueue队列只能存一个元素的原理,给生产者和消费者各放入一个该对象,
在生产和消费时利用该队列的阻塞功能控制向同一个阻塞队列BlockingQueue中放入和拿出元素
package com.study.concurrent.queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class Consumer<T> implements Runnable {
private BlockingQueue<T> queue;
private SynchronousQueue<T> synchronousQueue;
Consumer(BlockingQueue<T> queue) {
this.queue = queue;
this.synchronousQueue = new SynchronousQueue<>();
}
@Override
public void run() {
try {
while (true) {
consume(queue.take());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void consume(T t) {
try {
synchronousQueue.put(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//用户控制消费
public void expend(java.util.function.Consumer<T> consumer) {
try {
consumer.accept(synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.study.concurrent.queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class Producer<T> implements Runnable {
private final BlockingQueue<T> queue;
private SynchronousQueue<T> synchronousQueue;
public Producer(BlockingQueue<T> queue) {
this.queue = queue;
this.synchronousQueue = new SynchronousQueue<>();
}
@Override
public void run() {
try {
while (true) {
queue.put(produce());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private T produce() throws Exception {
return synchronousQueue.take();
}
//用户控制生产
public void product(T t) {
try {
synchronousQueue.put(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.study.concurrent.queue;
import java.util.*;
import java.util.concurrent.*;
/**
* @see java.util.Collection
* @see LinkedList
* @see PriorityQueue
* @see java.util.concurrent.LinkedBlockingQueue
* @see java.util.concurrent.BlockingQueue
* @see java.util.concurrent.ArrayBlockingQueue
* @see java.util.concurrent.LinkedBlockingQueue
* @see java.util.concurrent.PriorityBlockingQueue
* queue api:
* add() offer()
* remove() poll()
* element() peek()
* blocking queue api
* add offer put offer(timeout)
* remove poll take poll(time)
* element peek
*
*/
public class Test01 {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(5);
Producer<String> producer = new Producer<>(blockingQueue);
Consumer<String> consumer = new Consumer<>(blockingQueue);
new Thread(producer).start();
new Thread(consumer).start();
producer.product("abc");
producer.product("bcd");
producer.product("efg");
consumer.expend(t -> {
System.out.println(t.substring(0, 1).toUpperCase().concat(t.substring(1)));
});
consumer.expend(t -> {
System.out.println(t.toUpperCase());
});
consumer.expend(t -> {
System.out.println(Arrays.toString(t.split("")));
});
}
}