zoukankan      html  css  js  c++  java
  • 多线程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();
                    }
              }
          }
    
    }
  • 相关阅读:
    《大话数据结构》最小生成树——Prim算法
    《大话数据结构》图的BFS和DFS
    寒假集训日志(三)——数论
    寒假集训日志(二)——最小生成树,拓扑排序,欧拉回路,连通路
    set
    寒假集训日志(一)——图,最短路问题
    经典的图论算法,C++描述
    动态数组
    stack and queue
    最长递增子序列,最长公共子串,最长公共子序列问题,最长公共增长子序列问题
  • 原文地址:https://www.cnblogs.com/liaokailin/p/3797253.html
Copyright © 2011-2022 走看看