首页 > 代码库 > 多线程13-阻塞队列

多线程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();                }          }      }}