BlockQueue阻塞队列的使用


package com.thread_test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * Created by zhen on 2017-06-08.
 */
public class BlockQueueTest {
    /**
     * BlockingQueue 阻塞队列
     *  队列:先进先出
     *  存取元素主要三种方法:
     *       抛出异常 特殊值 阻塞 超时
         插入 add(e) offer(e) put(e) offer(e, time, unit)
         移除 remove() poll() take() poll(time, unit)
         检查 element() peek() 不可用 不可用
        几种方法的区别这里已经很明确了,就是存取元素失败的情况下的反应不同:抛异常,返回boolean 或者Null,阻塞
     *
     */

    /**
     * 三个空间的阻塞队列演示阻塞队列的效果
     * @param args
     */
    public static void main(String[] args){
        final BlockingQueue queue = new ArrayBlockingQueue(3);//定义3个单位的阻塞队列
        for(int i = 0; i < 2; i++){//放入数据
            new Thread(new Runnable() {
                public void run() {
                    while(true){
                        try {
                            Thread.sleep(1000);
                            String data = "xsadas";
                            System.out.println("线程" + Thread.currentThread().getName() + "准备放入数据");
                            queue.put(data);
                            System.out.println("线程" + Thread.currentThread().getName() + "放入数据:" + data + ",池子中有" + queue.size() + "个数据");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
        new Thread(new Runnable() {//取数据
            public void run() {
                while(true){
                    try {
                        Thread.sleep(1000);
                        System.out.println("线程" + Thread.currentThread().getName() + "准备取出数据");
                        String data = (String)queue.take();
                        System.out.println("线程" + Thread.currentThread().getName() + "取出数据:" + data + ", 池子中有" + queue.size() + "个数据");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

}

 

package com.thread_test;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * Created by zhen on 2017-06-08.
 * 使用阻塞队列实现线程间通信
 *
 * 阻塞队列和Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semphore通常是由同一方设置和释放信号量
 */
public class BlockQueueCommunication {



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

        for(int i = 0; i < 50; i++){
            business.main(i);
        }
    }

    static class Business{
        BlockingQueue queue1 = new ArrayBlockingQueue(1);
        BlockingQueue queue2 = new ArrayBlockingQueue(1);

        {
            try {
                queue1.put("1"); //往queue1放入元素,使得子线程阻塞,先走main
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void sub(int j){
            try {
                queue1.put("1"); //这里如果queue里面有元素就会阻塞
                System.out.println("sub Thread run time " + j);
                for(int i = 0; i<10; i++){
                    System.out.println("sub Thread out " + i);
                }
                queue2.take(); //取出另一个队列里面的元素,相当于唤醒放数据进队列的线程
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void main(int j){
            try {
                queue2.put("1");
                System.out.println("main Thread run time " + j);
                for(int i = 0; i<100; i++){
                    System.out.println("main Thread out " + i);
                }
                queue1.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

 

posted @ 2017-06-08 10:17  guodaxia  阅读(609)  评论(0)    收藏  举报