繁体   English   中英

如何让线程相互竞争?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM