多线程13-阻塞队列
1. 概念
阻塞队列的概念和前面提到的缓冲区的概念类似,常见一个固定长队的队列 ,如果队列满的时候 put数据则一致会阻塞等待,直到队列数据被取走后会立即执行put数据操作
同样的道理,如果队列为空时进行取数据take操作,则一直会阻塞等待,知道有线程执行了put数据到队列中后才会立即执行take数据的操作.
2.代码
package org.lkl.thead.foo; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class BlockQueueFoo { public static void main(String[] args) { ExecutorService threadPool = Executors.newCachedThreadPool() ; //申明一个长度为5的队列 final BlockingQueue<Long> queue = new ArrayBlockingQueue<Long>(5) ; //put操作 开启三个线程来put数据 for(int i = 1 ;i<=3 ;i++){ Runnable r = new Runnable() { @Override public void run() { while(true){ try { Thread.sleep(1000); Long r = new Random().nextLong() ; queue.put(r) ; System.out.println(Thread.currentThread().getName()+" put :"+r+" queue size:"+queue.size()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; threadPool.execute(r) ; } //开启一个线程取数据 new Thread(new Runnable() { @Override public void run() { while(true){ try { Thread.sleep(200); Long r = queue.take(); System.out.println(Thread.currentThread().getName()+" take "+ r+" queue size : "+queue.size()); } catch (Exception e) { // TODO: handle exception } } } }).start() ; } }
3. 通过阻塞队列来实现线程之间的通信
修改前面的代码 子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,然后再回到主线程又循环100次,如此循环50次 通过阻塞队列来实现线程之间的通信
代码:
package cn.itcast.heima2; import java.util.Collections; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.atomic.AtomicInteger; public class BlockingQueueCommunication { /** * @param args */ public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=50;i++){ business.sub(i); } } } ).start(); for(int i=1;i<=50;i++){ business.main(i); } } static class Business { BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1); BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1); { Collections.synchronizedMap(null); try { System.out.println("xxxxxdfsdsafdsa"); queue2.put(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void sub(int i){ try { queue1.put(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int j=1;j<=10;j++){ System.out.println("sub thread sequece of " + j + ",loop of " + i); } try { queue2.take(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void main(int i){ try { queue2.put(1); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } for(int j=1;j<=100;j++){ System.out.println("main thread sequece of " + j + ",loop of " + i); } try { queue1.take(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }