首页 新闻 搜索 专区 学院

生产者消费者模式究竟我写错哪里了?

0
[已解决问题] 解决于 2019-07-21 12:39

代码如下:
package thread.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

//生产者,添加队列
class Producer implements Runnable{
public BlockingQueue<String> blockingQueue;
private AtomicInteger count = new AtomicInteger();
private volatile boolean FLAG = true;
public Producer(BlockingQueue<String> blockingQueue){
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
System.out.println("生产者线程已经启动");
try{
while (FLAG){
String data = count.incrementAndGet()+"";
//生产出来之后,把数据存放到队列中
boolean offer = blockingQueue.offer(data,2, TimeUnit.SECONDS);
if(offer){
System.out.println("生产队列"+data+"成功了");
}else{
System.out.println("生产队列"+data+"失败了");
}
Thread.sleep(1000);
}

    }catch (Exception e){
    }finally {
    System.out.println(Thread.currentThread().getName()+"生产者线程停止");
    }

}
public void stop(){
    this.FLAG = false;
}

}

class ConstomerThread implements Runnable{
private volatile boolean FLAG = true;
private BlockingQueue<String> blockingQueue;
public ConstomerThread(BlockingQueue<String> blockingQueue){
this.blockingQueue = blockingQueue;
}

@Override
public void run() {
    System.out.println("消费者线程启动了");
    try{
    while (FLAG){

        String data = blockingQueue.poll(2,TimeUnit.SECONDS);
        if (data == null ){
            FLAG = false;
            System.out.println("消费者超过2秒为获取信息了");
            return;
        }
            System.out.println("消费者获取到的队列为:"+data);

    }
    }catch (Exception e){

    }finally {
        System.out.println("消费者已经停止了");
    }
}

}

public class Test004 {
public static void main(String[] args) {
BlockingQueue<String> bq = new LinkedBlockingQueue<String>(3);
Producer p = new Producer(bq);
ConstomerThread ct = new ConstomerThread(bq);

    Thread t1 = new Thread(p,"生产者");

    Thread t2 = new Thread(ct,"消费者");


    t1.start();
    t2.start();


    /*try {
        Thread.sleep(10*1000);
        p.stop();
    } catch (Exception e) {
        // TODO: handle exception
    }*/

}

}

运行结果如下:

消费者线程启动了
生产者线程已经启动
生产队列1成功了
消费者获取到的队列为:1
生产队列2成功了
消费者获取到的队列为:2
生产队列3成功了
消费者获取到的队列为:3
消费者获取到的队列为:4 //从这开始就不对了。为什么 会这样?
生产队列4成功了
生产队列5成功了
消费者获取到的队列为:5
生产队列6成功了
消费者获取到的队列为:6

lukely的主页 lukely | 初学一级 | 园豆:143
提问于:2019-03-24 02:06

如果你还是想不出来,就加个时间模块,在生产前加个时间,打印生产的时候再加个时间,同理在消费者中也加时间,比较时间值就可以知道了

开心的小草 2年前
< >
分享
最佳答案
0

这个不是问题呀。
2个线程,System.out.println出来的顺序本来就是调度相关的

奖励园豆:5
2012 | 高人七级 |园豆:21007 | 2019-03-24 16:09
其他回答(1)
0

这可能涉及到线程的抢占问题,就是说一个线程触发的时间片是有限的,可能线程1刚刚生产完还没打印,它的时间片到了它就要释放cpu,而此时线程2抢赢了线程1(线程抢占是随机的),cpu就运行线程2了然后线程2先打印了

开心的小草 | 园豆:243 (菜鸟二级) | 2019-03-24 23:08
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册