如何使线程相互竞争?

发布于 2025-01-23 18:19:42 字数 1635 浏览 0 评论 0原文

我目前正在为大学编程。在此程序中,我必须创建三个消费者,以围绕一批产品竞争。

对于产品库存,我使用了Hashmap< string,Integer>它保存在一个名为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();

有6种不同类型的产品的随机量,从5到10个在市场对象的哈希图中保存。

不允许螺纹池。

I'm currently programming a program for university. In this program I have to create three Consumerthreads which compete around a stock of products.

For the stock of products, I used a HashMap<String, Integer> which is saved in a class called marketplace.

My Consumer thread:

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

Now to my question, how can I program the threads in a way that they really compete around the product, because when I initialize the threads, the first one buys everything and the others get nothing.

The Threads are started like:

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

There are 6 different types of products in random amounts from 5 to 10 saved in the HashMap in the marketplace object.

Threadpools are not allowed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

漫漫岁月 2025-01-30 18:19:43

睡眠

看起来您的第一个任务在以后的任务有机会之前完成。

要模拟真正的买家,请引入一些随机的时间,让每个购买任务等待。

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

而且您需要主线程才能等到任务完成 - 请参阅本答案的下一部分,以了解有关使用executorService#等待等待完成的信息。

顺便说一句

,在现代Java中,我们很少需要直接解决thread类。取而代之的是,使用添加到Java 5中的执行者框架。

ExecutorService es = Executors.newFixedThreadPool( 3 ) ;
List< Consumer > tasks = … 
es.invokeAll( tasks ) ;
…

请参阅

我不明白为什么

您在消费者#购买方法上具有同步。 消费者类没有并发问题,因为您每个线程实例化一个。

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

Sleep

Looks like your first task completes before the later tasks have a chance.

To simulate real buyers, introduce some random amount of time for each buying task to wait.

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

And you need your main thread to wait until tasks are done — see next section of this Answer to learn about using ExecutorService#awaitTermination to wait for completion.

Executors

By the way, in modern Java we rarely need to address the Thread class directly. Instead, use the Executors framework added to Java 5.

ExecutorService es = Executors.newFixedThreadPool( 3 ) ;
List< Consumer > tasks = … 
es.invokeAll( tasks ) ;
…

See more code examples in my Answer I wrote yesterday on a similar Question. And search Stack Overflow to learn more, as executor services has been covered many many times already.

Other issues

I don’t see why you have synchronized on the Consumer#buy method. The Consumer class has no concurrency issues since you instantiate one per thread.

Perhaps you are using that as a way to make your Marketplace class thread-safe. If so, that is misplaced responsibility. Classes should generally be responsible for themselves, not others. You should rewrite Marketplace to attend to its own concurrency needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文