阻塞队列使用---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。