返回信息流这段代码是模拟生产者消费者问题,请问这段代码有什么问题吗?为什么运行时总是一个线程连着生产或消费10个然后其他线程继续呢?如果想要实现线程交替生产消费,应该怎样编写呢?
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ProducerAndConsumer {
private static final Integer FULL = 10;
private static ArrayList<Goods> cache=new ArrayList();
private static final int PRODUCER_NUM=4;
private static final int CUSTOMER_NUM=3;
public static void main(String[] args) {
ProducerAndConsumer producerAndConsumer=new ProducerAndConsumer();
ExecutorService pool= Executors.newCachedThreadPool();
for (int i=0;i<PRODUCER_NUM;i++){
pool.execute(producerAndConsumer.new Producer(i+1));
}
for (int i=0;i<CUSTOMER_NUM;i++){
pool.execute(producerAndConsumer.new Consumer(i+1));
}
}
static class Goods{
private static int id=0;
Goods(){id++;}
@Override
public String toString() {
return "Goods"+id;
}
}
class Producer implements Runnable{
private final int id;
Producer(int id){this.id=id;}
@Override
public void run() {
while (true){
synchronized (cache){
while (cache.size()==FULL){
try {
cache.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
cache.add(new Goods());
System.out.println("Producer "+id+" put in cache. Cache size is "+cache.size());
cache.notifyAll();
}
}
}
}
class Consumer implements Runnable{
private final int id;
Consumer(int id){this.id=id;}
@Override
public void run() {
while (true){
synchronized (cache){
while (cache.size()==0){
try {
cache.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
cache.remove(0);
System.out.println("Consumer "+id+" fetch from cache. Cache size is "+cache.size());
cache.notifyAll();
}
}
}
}
}
这是一条镜像帖。来源:北邮人论坛 / java / #64232同步于 2020/8/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
【问题】Java生产者消费者多线程问题
lxx909546478
2020/8/14镜像同步11 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
补充一下运行结果:
Producer 1 put in cache. Cache size is 1
Producer 1 put in cache. Cache size is 2
Producer 1 put in cache. Cache size is 3
Producer 1 put in cache. Cache size is 4
Producer 1 put in cache. Cache size is 5
Producer 1 put in cache. Cache size is 6
Producer 1 put in cache. Cache size is 7
Producer 1 put in cache. Cache size is 8
Producer 1 put in cache. Cache size is 9
Producer 1 put in cache. Cache size is 10
Consumer 3 fetch from cache. Cache size is 9
Consumer 3 fetch from cache. Cache size is 8
Consumer 3 fetch from cache. Cache size is 7
Consumer 3 fetch from cache. Cache size is 6
Consumer 3 fetch from cache. Cache size is 5
Consumer 3 fetch from cache. Cache size is 4
Consumer 3 fetch from cache. Cache size is 3
Consumer 3 fetch from cache. Cache size is 2
Consumer 3 fetch from cache. Cache size is 1
Consumer 3 fetch from cache. Cache size is 0
Producer 4 put in cache. Cache size is 1
Producer 4 put in cache. Cache size is 2
Producer 4 put in cache. Cache size is 3
Producer 4 put in cache. Cache size is 4
Producer 4 put in cache. Cache size is 5
Producer 4 put in cache. Cache size is 6
Producer 4 put in cache. Cache size is 7
Producer 4 put in cache. Cache size is 8
Producer 4 put in cache. Cache size is 9
Producer 4 put in cache. Cache size is 10
对的,生产者消费者问题的缓冲区好像只有一个线程能同时进入,这好像是题目的条件?
【 在 xuanyu66 (angry_yang) 的大作中提到: 】
: annd,这个代码还有一个问题就是读和取是互相阻塞的。但是其实这两者没啥并发关系
是,因为之前一直用semaphore,想试试用wait ¬ify,结果写出来感觉不太对hhh
【 在 xuanyu66 (angry_yang) 的大作中提到: 】
: and,感觉用reetrantlock和condition搭配比较好,因为可读可写其实是两个状态,代码看起来也易读一些
现在看起来正常多了,感谢[ema3]
【 在 xuanyu66 (angry_yang) 的大作中提到: 】
: 两个synchronized代码块后加一个thread.yield()。
: 或者sleep一下都行
好的,谢谢你。我之后会尝试多用lambda表达式替代匿名内部类的[ema3]我个人用的一直不太熟练hhh
【 在 q527319547 (AtOm98bj) 的大作中提到: 】
: 提个建议 用lambda表达式写 new thread().start 这样可读性好很多