如何使线程相互竞争?



我目前正在为大学编写程序。在这个程序中,我必须创建三个consumerthread,它们围绕一个产品库存进行竞争。

对于产品库存,我使用HashMap<String,>它被保存在一个名为marketplace的类中。

我的消费者线程:

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();

在marketplace对象的HashMap中有6种不同类型的产品,随机数量从5到10不等。

不允许使用线程池

睡眠

看起来你的第一个任务在后面的任务有机会之前完成了。

为了模拟真实的买家,为每个购买任务引入一些随机的等待时间。

int millis = ThreadLocalRandom.current().nextInt( 5 , 1_000 ) ;
Thread.sleep( millis ) ;

你需要你的主线程等待直到任务完成-请参阅本答案的下一节了解如何使用ExecutorService#awaitTermination等待完成。

<标题>执行人h1>
ExecutorService es = Executors.newFixedThreadPool( 3 ) ;
List< Consumer > tasks = … 
es.invokeAll( tasks ) ;
…

查看我昨天写的关于类似问题的答案中的更多代码示例。搜索Stack Overflow可以了解更多信息,因为执行器服务已经被介绍过很多次了。

<标题>

其他问题我不明白为什么在Consumer#buy方法上有synchronizedConsumer类没有并发性问题,因为每个线程实例化一个。

也许你正在使用它作为一种方式,使你的Marketplace类线程安全。如果是这样,这是一种错位的责任。类通常应该对自己负责,而不是对其他类负责。您应该重写Marketplace以满足其自身的并发需求。