zoukankan      html  css  js  c++  java
  • 阻塞队列使用ArrayBlockingQueue

      ArrayBlockingQueue是JAVA5中的一个阻塞队列,能够自定义队列大小,当插入时,如果队列已经没有空闲位置,那么新的插入线程将阻塞到该队列,一旦该队列有空闲位置,那么阻塞的线程将执行插入。从队列中取数据为:take,放数据为:put。下面的例子模拟了两个队列的插入和获取,首先在队列2中插入一个数据,启动线程2向队列2中插入数据时,该线程将阻塞在队列2等待,同时启动线程1向队列1中插入数据,由于队列1此时为空那么能够正确插入,然后从队列2中取数据,当线程1再次插入时,阻塞到队列1,此时,阻塞在队列2的线程2能够插入,并且从队列1中取数据,此时线程1能够插入,如此往复50次,并且每次插入成功后都循环输出10次。代码如下:

    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    
    public class ArrayBlockingCommunication {
    
    	public static void main(String[] args) {
    		
    		final Business business = new Business();
    		
    		new Thread(new Runnable(){
    
    			public void run() {
    				for(int i=0; i<50; i++){
    					business.sub(i);
    				}
    			}
    			
    		}).start();
    		
    		
    		new Thread(new Runnable(){
    
    			public void run() {
    				for(int i=0; i<50; i++){
    					business.main(i);
    				}
    			}
    			
    		}).start();
    		
    	}
    	
    	
    	
    	static class Business{
    		
    		BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
    		BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
    
    		{
    			try{
    				queue2.put(1);
    			}catch(Exception e){
    				e.printStackTrace();
    			}
    		}
    		
    		public void sub(int i){
    			
    			
    			try {
    				queue1.put(1);
    				System.out.println("线程" + Thread.currentThread().getName() + 
    				"正在阻塞");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			System.out.println("线程" + Thread.currentThread().getName() + 
    			"开始运行");
    			for(int j=1; j<=10; j++){
    				System.out.println("sub thread sequence is " + j + " loop of " + i);
    			}
    			try {
    				queue2.take();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		
    		
    		
    		public void main(int i){
    			
    			try {
    				queue2.put(1);
    				System.out.println("线程" + Thread.currentThread().getName() + 
    						"正在阻塞");
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println("线程" + Thread.currentThread().getName() + 
    			"开始运行");
    			for(int j=1; j<=10; j++){
    				System.out.println("main thread sequence is " + j + " loop of " + i);
    			}
    			try {
    				queue1.take();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }
    

    请大家注意:在Business类中有一个匿名构造函数,其特点如下:

    匿名构造方法,在任何构造方法之前被调用。这样保证我们初始化Business类时已经向队列2中插入了数据,这样执行起来保证我们看到的线程1先运行,然后是线程2。

      

  • 相关阅读:
    正则:匹配以某字符串结尾或不以某字符串结尾的字符串或包含某字符并且不以某字符串结尾的字符串
    【访问网络资源出错】不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接
    运行 TSQL 调试器之前配置防火墙规则
    SQL Server的照合顺序的含义
    eclipse svn is already locked解决方案
    Python 如何提取邮件内容
    Python 一招搞定禅道提交bug
    Python 实现Excel自动化办公《下》
    Python 实现Excel自动化办公《中》
    Python 实现Excel自动化办公《上》
  • 原文地址:https://www.cnblogs.com/belen/p/2446019.html
Copyright © 2011-2022 走看看