多线程(7)-阻塞队列

本文主要说下阻塞队列BlockQueue

队列是先进先出的,创建时可以固定大小,也可以不固定。

BlockQueue有很多实现,这里简单介绍ArrayBlockingQueue;

在增加时阻塞,和删除时为空,查看帮助文档

put() 阻塞住直到然后放入,take()

offer()返回false,poll()返回null

add()抛异常 ,remove()抛异常

上代码

public class BlockingQueueTest {
    public static void main(String[] args) {
        final BlockingQueue queue = new ArrayBlockingQueue(3);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                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 (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }).start();
        }

        new Thread(() -> {
            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 (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

这里给一个玩味例子,利用阻塞队列玩玩同步通知

public class BlockingQueueCommunication {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		final Business business = new Business();
		new Thread(
				() -> {
                    for(int i=1;i<=50;i++){
                        business.sub(i);
                    }
                }
		).start();
		for(int i=1;i<=50;i++){
			business.main(i);
		}
	}

	 static class Business {
		 
		  BlockingQueue queue1 = new ArrayBlockingQueue(1);
		  BlockingQueue queue2 = new ArrayBlockingQueue(1);
		  
		  {
			  Collections.synchronizedMap(null);
			  try {
				  System.out.println("xxxxxdfsdsafdsa");
				queue2.put(1);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  }
		  
		  public  void sub(int i){
			  	try {
					queue1.put(1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int j=1;j<=10;j++){
					System.out.println("sub thread sequece of " + j + ",loop of " + i);
				}
				try {
					queue2.take();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  }
		  
		  public  void main(int i){
			  	try {
					queue2.put(1);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				for(int j=1;j<=100;j++){
					System.out.println("main thread sequece of " + j + ",loop of " + i);
				}
				try {
					queue1.take();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  }
	  }

}

队列put时阻塞了,只有等到take()的时候,才能继续put(),这样线程间就有一个通信了。蛮有意思。

JDK1.8中的阻塞队列实现共有7个,分别是ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue、SynchronousQueue、LinkedTransferQueue以及LinkedBlockingDeque,下面资料对他们进行一个简单的分析。转自此处;里面总结的还可以,我们自己也可以看手册和源码嘛。有时间再总结,先睡觉了。

 

 

你可能感兴趣的:(多线程,Java多线程和并发库,多线程)