[英]How to make threads compete against each other?
我目前正在为大学编写程序。 在这个程序中,我必须创建三个消费者线程,它们围绕产品库存进行竞争。
对于产品库存,我使用了一个 HashMap<String, Integer>,它保存在一个名为 marketplace 的 class 中。
我的消费者线程:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class consumer implements Runnable{
List<String> productTypes = new ArrayList<>();
Map<String, Integer> productsBought = new HashMap<>();
marketplace marketplace;
public consumer( marketplace marketplace) {
this.marketplace = marketplace;
}
@Override
public void run() {
buy();
this.marketplace.addProductsBought(this.productsBought);
}
public synchronized void buy(){
int bought =0;
this.productTypes = this.marketplace.getProductTypes();
for(int i = 0; i<this.productTypes.size(); i++){
String productType = this.productTypes.get(i);
bought = this.marketplace.buyProduct(productType);
this.productsBought.put(productType, bought);
}
}
}
现在我的问题是,我如何才能以真正围绕产品竞争的方式对线程进行编程,因为当我初始化线程时,第一个购买所有东西而其他人什么也得不到。
线程启动如下:
Runnable consumerOne = new consumer(marketplace);
Runnable consumerTwo = new consumer(marketplace);
Runnable consumerThree = new consumer(marketplace);
Thread consumerOneThread = new Thread(consumerOne);
Thread consumerTwoThread = new Thread(consumerTwo);
Thread consumerThreeThread = new Thread(consumerThree);
consumerOneThread.start();
consumerTwoThread.start();
consumerThreeThread.start();
商城object的HashMap中保存了6种不同数量的商品,数量从5到10不等。
不允许使用线程池。
看起来你的第一个任务在后面的任务有机会之前完成。
为了模拟真实的买家,为每个购买任务引入一些随机的等待时间。
int millis = ThreadLocalRandom.current().nextInt( 5 , 1_000 ) ;
Thread.sleep( millis ) ;
并且您需要主线程等待任务完成——请参阅本答案的下一部分以了解如何使用ExecutorService#awaitTermination
等待完成。
顺便说一句,在现代 Java 中,我们很少需要直接寻址Thread
class。 相反,使用添加到 Java 5 的 Executors 框架。
ExecutorService es = Executors.newFixedThreadPool( 3 ) ;
List< Consumer > tasks = …
es.invokeAll( tasks ) ;
…
在我昨天写的类似问题的答案中查看更多代码示例。 并搜索 Stack Overflow 以了解更多信息,因为执行程序服务已经被覆盖了很多次。
我不明白你为什么在Consumer#buy
方法上synchronized
。 Consumer
class 没有并发问题,因为您为每个线程实例化一个。
也许您正在使用它来使您的Marketplace
class 线程安全。 如果是这样,那就是错位的责任。 班级通常应该对自己负责,而不是对他人负责。 您应该重写Marketplace
以满足其自身的并发需求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.