BlockingQueue为Java1.5版本之后并发包下的接口,实现其功能大多为阻塞队列,特点为线程安全适合多线程下的数据操作。
利用阻塞队列的特征可以轻易完成生产者与消费者的多线程同步问题
注意的问题:
1.多个线程需要公用一个阻塞队列对象
2.AtomicInteger对象的自增为原子性,多线程环境下不会出现“脏读”问题
3.blockQueue .offer(A,B,C),A参数为放进去的值,B为阻塞时间,C为阻塞时间的单位。如果队列满了就等待B时间,如果时间到了队列不满就入队并返回true,否则就放弃入队返回false
4.反之poll为出队,blockQueue.poll(A,B),A表示阻塞时间,B表示时间单位,如果队列空了就等待A时间,如果时间到了不为空就返回出队的对象,如果时间到了队列还为空就返回null
class ProducerQueue implements Runnable{private volatile BlockingQueue<Integer> blockQueue;private AtomicInteger atomicInteger=new AtomicInteger(0);private Boolean flag=true;public void setBlockQueue(BlockingQueue<Integer> blockQueue) {this.blockQueue = blockQueue;}public AtomicInteger getAtomicInteger() {return this.atomicInteger;}@Overridepublic void run() {System.out.println("生产者开始运行");try {while(flag) {int incrementAndGet = atomicInteger.incrementAndGet();boolean offer = blockQueue.offer(incrementAndGet, 2, TimeUnit.SECONDS);if (offer) {System.out.println("生产者成功生产了:"+incrementAndGet);}else {System.out.println("生产者失败:"+incrementAndGet);}Thread.sleep(1000);}} catch (Exception e) {e.printStackTrace();} finally {System.out.println("生产者结束");}}public void setFlag(Boolean flag) {this.flag=flag;}}class CustomerQueue implements Runnable{private volatile BlockingQueue<Integer> blockQueue;private Boolean flag=true;public void setBlockQueue(BlockingQueue<Integer> blockQueue) {this.blockQueue = blockQueue;}@Overridepublic void run() {try {System.out.println("消费者开始运行");while(flag) {Integer poll = blockQueue.poll(2, TimeUnit.SECONDS);if (poll==null) {System.out.println("超过2秒没有取到值");return ;}else {System.out.println("消费者消费到了数据:"+poll);}}} catch (Exception e) {// TODO: handle exception}finally {System.out.println("消费者结束");}}}public class MyQueue {public static void main(String[] args) {LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<Integer>(10);ProducerQueue producerQueue = new ProducerQueue();CustomerQueue customerQueue = new CustomerQueue();producerQueue.setBlockQueue(linkedBlockingQueue);customerQueue.setBlockQueue(linkedBlockingQueue);Thread thread = new Thread(producerQueue);Thread thread2 = new Thread(customerQueue);thread.start();thread2.start();while(true) {AtomicInteger atomicInteger = producerQueue.getAtomicInteger();if (atomicInteger.get()==10) {producerQueue.setFlag(false);break;}}}}