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