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();
                    }
              }
          }
    
    }
  • 相关阅读:
    changing a pointer rather than erasing memory cells
    验证码识别 edge enhancement 轮廓增强 region finding 区域查找
    Manipulating Data Structures
    passing parameters by value is inefficient when the parameters represent large blocks of data
    Aliasing 走样
    Artificial Intelligence Research Methodologies 人工智能研究方法
    Thread safety
    include pointers as a primitive data type
    flat file
    functional cohesion
  • 原文地址:https://www.cnblogs.com/liaokailin/p/3797253.html
Copyright © 2011-2022 走看看