一个关于多线程 阻塞队列的排序有关问题.
一个关于多线程 阻塞队列的排序问题.....
最近小弟在了解阻塞队列的相关知识, 阻塞队列是FIFO, put ,take 一个阻塞插入新的在队尾 , 一个阻塞取队头 经过简单的测试, 确实如此,先被put进的,先会take 出 ,但是 参考了一个生产者与消费者的例子,自己的代码却是后进先出的,即 消费者take时 总是取到 生产者在后面put放入的元素 ,而不是 生产者在队头put放入的元素 , 阻塞队列 的 实现方式为 ArrayBlockingQueue 具体代码如下所示,希望有时间的各位侠士不吝赐教
public class BlockingQueueTest {
/**定义装苹果的篮子*/
public static class Basket{
//定义变量为i,初始值为0,每次生产者put进队列时,自动加1
private int i=0;
//篮子,能够容纳3个苹果
BlockingQueue<Apple> basket = new ArrayBlockingQueue<Apple>(3,true);
//
Apple ap=new Apple();
//生产苹果,放入篮子
public void produce() throws InterruptedException{
//put方法放入一个苹果,若basket满了,等到basket有位置
ap.name="APPLE"+i;
ap.size=i;
basket.put(ap);
i++;
System.out.println("生产者放入苹果 "+ap.name+" 大小为"+ap.size+ " 时间为 "+ + System.currentTimeMillis());
}
//消费苹果,从篮子中取走
public Apple consume() throws InterruptedException{
//take方法取出一个苹果,若basket为空,等到basket有苹果为止
Apple ap=basket.take();
// System.out.println("数组"+basket.toArray()[0]);
System.out.println("消费者取出苹果 "+ ap.name+ " 大小为 "+ap.size);
return ap;
//return null;
}
}
//定义苹果 ,属性为 name size 都是生产者每生产一次,自动+1
public static class Apple{
String name;
int size;
}
//测试方法
public static void testBasket(){
final Basket basket = new Basket();//建立一个装苹果的篮子
//定义苹果生产者
class Producer implements Runnable{
public void run(){
try{
while(true){
//生产苹果
System.out.println("生产者准备生产苹果: 时间为 " + System.currentTimeMillis());
basket.produce();
System.out.println("生产者生产苹果完毕: 时间为 " + System.currentTimeMillis());
//休眠300ms
Thread.sleep(300);
}
}catch(InterruptedException ex){
}
}
}
//定义苹果消费者
class Consumer implements Runnable{
public void run(){
try{
while(true){
//消费苹果
System.out.println("消费者准备消费苹果: " + System.currentTimeMillis());
basket.consume();
System.out.println("消费者消费苹果完毕: " + System.currentTimeMillis());
//休眠1000ms
Thread.sleep(1000);
}
}catch(InterruptedException ex){
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer();
Consumer consumer = new Consumer();
service.submit(producer);
service.submit(consumer);
//
// new Thread( new Producer()).start();
//
// new Thread( new Consumer()).start();
//程序运行5s后,所有任务停止
try{
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("队列中的第一个苹果"+basket.basket.peek().name);
}catch(InterruptedException ex){
}
service.shutdownNow();
}
public static void main(String[] args){
BlockingQueueTest.testBasket();
}
}
//测试结果为
/*生产者准备生产苹果: 时间为 1416409225306
生产者放入苹果 APPLE0 大小为0 时间为 1416409225306
生产者生产苹果完毕: 时间为 1416409225306
消费者准备消费苹果: 1416409225306
消费者取出苹果 APPLE0 大小为 0
消费者消费苹果完毕: 1416409225306
生产者准备生产苹果: 时间为 1416409225618
生产者放入苹果 APPLE1 大小为1 时间为 1416409225618
生产者生产苹果完毕: 时间为 1416409225618
生产者准备生产苹果: 时间为 1416409225930
生产者放入苹果 APPLE2 大小为2 时间为 1416409225930
生产者生产苹果完毕: 时间为 1416409225930
生产者准备生产苹果: 时间为 1416409226242
生产者放入苹果 APPLE3 大小为3 时间为 1416409226242
生产者生产苹果完毕: 时间为 1416409226242
消费者准备消费苹果: 1416409226321
消费者取出苹果 APPLE3 大小为 3
消费者消费苹果完毕: 1416409226321
生产者准备生产苹果: 时间为 1416409226555
生产者放入苹果 APPLE4 大小为4 时间为 1416409226555
生产者生产苹果完毕: 时间为 1416409226555
生产者准备生产苹果: 时间为 1416409226867
消费者准备消费苹果: 1416409227335
生产者放入苹果 APPLE5 大小为5 时间为 1416409227335
生产者生产苹果完毕: 时间为 1416409227335
消费者取出苹果 APPLE5 大小为 5
消费者消费苹果完毕: 1416409227335
生产者准备生产苹果: 时间为 1416409227648
消费者准备消费苹果: 1416409228350
生产者放入苹果 APPLE6 大小为6 时间为 1416409228350
生产者生产苹果完毕: 时间为 1416409228350
消费者取出苹果 APPLE6 大小为 6
消费者消费苹果完毕: 1416409228350
生产者准备生产苹果: 时间为 1416409228663
消费者准备消费苹果: 1416409229365
生产者放入苹果 APPLE7 大小为7 时间为 1416409229365
生产者生产苹果完毕: 时间为 1416409229365
消费者取出苹果 APPLE7 大小为 7
消费者消费苹果完毕: 1416409229365
生产者准备生产苹果: 时间为 1416409229678
队列中的第一个苹果APPLE8*/
------解决思路----------------------
格式化一下
最近小弟在了解阻塞队列的相关知识, 阻塞队列是FIFO, put ,take 一个阻塞插入新的在队尾 , 一个阻塞取队头 经过简单的测试, 确实如此,先被put进的,先会take 出 ,但是 参考了一个生产者与消费者的例子,自己的代码却是后进先出的,即 消费者take时 总是取到 生产者在后面put放入的元素 ,而不是 生产者在队头put放入的元素 , 阻塞队列 的 实现方式为 ArrayBlockingQueue 具体代码如下所示,希望有时间的各位侠士不吝赐教
public class BlockingQueueTest {
/**定义装苹果的篮子*/
public static class Basket{
//定义变量为i,初始值为0,每次生产者put进队列时,自动加1
private int i=0;
//篮子,能够容纳3个苹果
BlockingQueue<Apple> basket = new ArrayBlockingQueue<Apple>(3,true);
//
Apple ap=new Apple();
//生产苹果,放入篮子
public void produce() throws InterruptedException{
//put方法放入一个苹果,若basket满了,等到basket有位置
ap.name="APPLE"+i;
ap.size=i;
basket.put(ap);
i++;
System.out.println("生产者放入苹果 "+ap.name+" 大小为"+ap.size+ " 时间为 "+ + System.currentTimeMillis());
}
//消费苹果,从篮子中取走
public Apple consume() throws InterruptedException{
//take方法取出一个苹果,若basket为空,等到basket有苹果为止
Apple ap=basket.take();
// System.out.println("数组"+basket.toArray()[0]);
System.out.println("消费者取出苹果 "+ ap.name+ " 大小为 "+ap.size);
return ap;
//return null;
}
}
//定义苹果 ,属性为 name size 都是生产者每生产一次,自动+1
public static class Apple{
String name;
int size;
}
//测试方法
public static void testBasket(){
final Basket basket = new Basket();//建立一个装苹果的篮子
//定义苹果生产者
class Producer implements Runnable{
public void run(){
try{
while(true){
//生产苹果
System.out.println("生产者准备生产苹果: 时间为 " + System.currentTimeMillis());
basket.produce();
System.out.println("生产者生产苹果完毕: 时间为 " + System.currentTimeMillis());
//休眠300ms
Thread.sleep(300);
}
}catch(InterruptedException ex){
}
}
}
//定义苹果消费者
class Consumer implements Runnable{
public void run(){
try{
while(true){
//消费苹果
System.out.println("消费者准备消费苹果: " + System.currentTimeMillis());
basket.consume();
System.out.println("消费者消费苹果完毕: " + System.currentTimeMillis());
//休眠1000ms
Thread.sleep(1000);
}
}catch(InterruptedException ex){
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer();
Consumer consumer = new Consumer();
service.submit(producer);
service.submit(consumer);
//
// new Thread( new Producer()).start();
//
// new Thread( new Consumer()).start();
//程序运行5s后,所有任务停止
try{
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("队列中的第一个苹果"+basket.basket.peek().name);
}catch(InterruptedException ex){
}
service.shutdownNow();
}
public static void main(String[] args){
BlockingQueueTest.testBasket();
}
}
//测试结果为
/*生产者准备生产苹果: 时间为 1416409225306
生产者放入苹果 APPLE0 大小为0 时间为 1416409225306
生产者生产苹果完毕: 时间为 1416409225306
消费者准备消费苹果: 1416409225306
消费者取出苹果 APPLE0 大小为 0
消费者消费苹果完毕: 1416409225306
生产者准备生产苹果: 时间为 1416409225618
生产者放入苹果 APPLE1 大小为1 时间为 1416409225618
生产者生产苹果完毕: 时间为 1416409225618
生产者准备生产苹果: 时间为 1416409225930
生产者放入苹果 APPLE2 大小为2 时间为 1416409225930
生产者生产苹果完毕: 时间为 1416409225930
生产者准备生产苹果: 时间为 1416409226242
生产者放入苹果 APPLE3 大小为3 时间为 1416409226242
生产者生产苹果完毕: 时间为 1416409226242
消费者准备消费苹果: 1416409226321
消费者取出苹果 APPLE3 大小为 3
消费者消费苹果完毕: 1416409226321
生产者准备生产苹果: 时间为 1416409226555
生产者放入苹果 APPLE4 大小为4 时间为 1416409226555
生产者生产苹果完毕: 时间为 1416409226555
生产者准备生产苹果: 时间为 1416409226867
消费者准备消费苹果: 1416409227335
生产者放入苹果 APPLE5 大小为5 时间为 1416409227335
生产者生产苹果完毕: 时间为 1416409227335
消费者取出苹果 APPLE5 大小为 5
消费者消费苹果完毕: 1416409227335
生产者准备生产苹果: 时间为 1416409227648
消费者准备消费苹果: 1416409228350
生产者放入苹果 APPLE6 大小为6 时间为 1416409228350
生产者生产苹果完毕: 时间为 1416409228350
消费者取出苹果 APPLE6 大小为 6
消费者消费苹果完毕: 1416409228350
生产者准备生产苹果: 时间为 1416409228663
消费者准备消费苹果: 1416409229365
生产者放入苹果 APPLE7 大小为7 时间为 1416409229365
生产者生产苹果完毕: 时间为 1416409229365
消费者取出苹果 APPLE7 大小为 7
消费者消费苹果完毕: 1416409229365
生产者准备生产苹果: 时间为 1416409229678
队列中的第一个苹果APPLE8*/
------解决思路----------------------
格式化一下
public class BlockingQueueTest {
/**定义装苹果的篮子*/
public static class Basket{
//定义变量为i,初始值为0,每次生产者put进队列时,自动加1
private int i=0;
//篮子,能够容纳3个苹果
BlockingQueue<Apple> basket = new ArrayBlockingQueue<Apple>(3,true);
//
Apple ap=new Apple();
//生产苹果,放入篮子
public void produce() throws InterruptedException{
//put方法放入一个苹果,若basket满了,等到basket有位置
ap.name="APPLE"+i;
ap.size=i;
basket.put(ap);
i++;
System.out.println("生产者放入苹果 "+ap.name+" 大小为"+ap.size+ " 时间为 "+ + System.currentTimeMillis());
}
//消费苹果,从篮子中取走
public Apple consume() throws InterruptedException{
//take方法取出一个苹果,若basket为空,等到basket有苹果为止
Apple ap=basket.take();
// System.out.println("数组"+basket.toArray()[0]);
System.out.println("消费者取出苹果 "+ ap.name+ " 大小为 "+ap.size);
return ap;
//return null;
}
}
//定义苹果 ,属性为 name size 都是生产者每生产一次,自动+1
public static class Apple{
String name;
int size;
}
//测试方法
public static void testBasket(){
final Basket basket = new Basket();//建立一个装苹果的篮子
//定义苹果生产者
class Producer implements Runnable{
public void run(){
try{
while(true){
//生产苹果
System.out.println("生产者准备生产苹果: 时间为 " + System.currentTimeMillis());
basket.produce();
System.out.println("生产者生产苹果完毕: 时间为 " + System.currentTimeMillis());
//休眠300ms
Thread.sleep(300);
}
}catch(InterruptedException ex){
}
}
}
//定义苹果消费者
class Consumer implements Runnable{
public void run(){
try{
while(true){
//消费苹果
System.out.println("消费者准备消费苹果: " + System.currentTimeMillis());
basket.consume();
System.out.println("消费者消费苹果完毕: " + System.currentTimeMillis());
//休眠1000ms
Thread.sleep(1000);
}
}catch(InterruptedException ex){
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer();
Consumer consumer = new Consumer();
service.submit(producer);
service.submit(consumer);
//
// new Thread( new Producer()).start();
//
// new Thread( new Consumer()).start();
//程序运行5s后,所有任务停止
try{
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
System.out.println("队列中的第一个苹果"+basket.basket.peek().name);
}catch(InterruptedException ex){
}
service.shutdownNow();
}
public static void main(String[] args){
BlockingQueueTest.testBasket();
}
}