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