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();
            }
        }
    }

}

 

posted @ 2016-11-09 01:18  wq3435  阅读(3140)  评论(1编辑  收藏  举报