Java多線程與並發庫高級應用-可阻塞的隊列


ArrayBlockQueue 可阻塞的隊列

  > 隊列包含固定長度的隊列和不固定長度的隊列。

  > ArrayBlockQueue

    > 看BlockingQueue類的幫助文檔,其中有各個方法的區別對比的表格。

    > 只有put方法和 take 方法才具有阻塞功能

  > 用3個空間的隊列來演示阻塞隊列的功能和效果

/*
 * 兩個線程向隊列中放數據,一個線程從隊列中取數據
 */
public class BlockingQueueTest {

    public static void main(String[] args) {
        final BlockingQueue queue = new ArrayBlockingQueue(3);
        for(int i = 0;i<2;i++){
            new Thread(){
                public void run() {
                    while(true){
                        try {
                            Thread.sleep((long)(Math.random()*1000));
                            System.out.println(Thread.currentThread().getName()
                                    +"准備放數據");
                            queue.put(1);
                            System.out.println(Thread.currentThread().getName()
                                    +"隊列目前有"+queue.size()+"個數據");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
            }.start();
        }
        
        new Thread(){
            public void run() {
                while(true){
                    try {
                        //將此處的睡眠時間分別改為100和1000,觀察運行結果
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName()
                                +"准備取數據");
                        queue.take();
                        System.out.println(Thread.currentThread().getName()
                                +"隊列目前有"+queue.size()+"個數據");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

}

 

 

   >用兩個具有1個空間的隊列來實現同步通知的功能

/**
 * 改造之前的程序,用兩個具有1個空間的隊列來實現同步通知的功能
 * 使用阻塞隊列實現 
 * 子線程循環10次,接着主線程循環100次,接着又回到子線程循環10次,接着又 主線程循環100次,如此循環50次,請寫出程序
 * 
 * @author Administrator
 * 
 */
public class BlockingQueueCommunication {

    public static void main(String[] args) {
        final Business5 business = new Business5();
        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 Business5 {
        BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<>(1);
        BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<>(1);
        //這種寫法叫 匿名構造方法,運行時機在任何構造方法之前,創建多少個對象就會調用多少次, 而static{} 靜態代碼塊在類加載的時候調用且只調用一次
        {
            try {
                queue2.put(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void sub(int i) {
            try {
                queue1.put(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int j = 1; j <= 100; j++) {
                System.out.println("sub thread sequence of " + j + ", loop of "
                        + i);
            }
            try {
                queue2.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void main(int i) {
            try {
                queue2.put(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("main thread sequence of " + j
                        + ", loop of " + i);
            }
            try {
                queue1.take();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM