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。
