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

}

 

 

 

 

 

posted @ 2014-06-19 17:55  廖凯林  阅读(280)  评论(0编辑  收藏  举报