平时使用的队列是制定好个数以后,如果放入如的数据超过了队列设定的个数就会报错,在java多线程中有一个阻塞队列,这个类是对Queue在多线程中使用的扩展,当作为临界资源的时候,这个队列是安全的,即存放数据如果超过了队列设定好的初始数据的时候,放入数据的线程将会处于等待状态。
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 (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
new Thread() {
public void run() {
while (true) {
try {
/*休眠*/
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();
}
}
我们可以利用阻塞队列的原理来实现不同线程之间的交替执行,思路:使用两个只具有一个空间的队列,队列一满就切换,从而达到子线程执行10次,主线程执行100次,来回切换50次的效果:
public class BlockingQueueCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(
new Runnable() {
@Override
public void run() {
/*子线程总共循环50次*/
for(int i=1;i<=50;i++){
business.sub(i);
}
}
}
).start();
/*主线程总共循环50次*/
for(int i=1;i<=50;i++){
business.main(i);
}
}
static class Business {
/*创建具有一个控件的队列1*/
BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
/*创建具有两个控件的队列2*/
BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
/*这是一个默认构造函数*/
{
//Collections.synchronizedMap(null);
try {
/*往队列2中添加数据*/
queue2.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 子线程执行方法
* @param i
*/
public void sub(int i){
try {
/*往队列1中存数据*/
queue1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
/*子线程循环10次*/
for(int j=1;j<=10;j++){
System.out.println("子线程循环: " + j + ",总共循环: " + i);
}
try {
/*从队列2中取数据*/
queue2.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 主线程执行方法
* @param i
*/
public void main(int i){
try {
/*往队列2中存数据*/
queue2.put(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
/*主线程循环100次*/
for(int j=1;j<=100;j++){
System.out.println("主线程循环: " + j + ",总共循环: " + i);
}
try {
/*从队列1中去数据*/
queue1.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}