繁体   English   中英

使用 While 循环的多线程

[英]Multithreading with a While Loop

下面是我的代码,买卖双方与汽车和汽车展厅进行互动。 据我所知,它按预期运行。 但是,线程仅在 Main 的 While 循环中运行 20+ 天后才运行。 谁能帮忙指出这是为什么?

public static void main(String[] args) {

    CarShowroom carShowroom = new CarShowroom();
    Random rand = new Random();

    int day = 1;

    while (day <= 30){
       System.out.println("Day " + day + " beginning. There are " + carShowroom.getCars().size()  + " cars in the showroom today.");

        int randomSeller = rand.nextInt(3);
        int randomBuyer = rand.nextInt(3);

        for (int j = 0; j <= randomSeller; j++){
            Seller seller = new Seller(carShowroom);
            Thread mySellerThread = new Thread(seller);
            mySellerThread.start();
        }

        for (int i = 0; i <= randomBuyer; i++){
            Buyer buyer = new Buyer(carShowroom);
            Thread myBuyerThread = new Thread(buyer);
            myBuyerThread.start();
        }

        day++;
    }
}

}

我认为您的循环执行速度可能比 Thread.start() 启动速度更快。

这要么是因为生成的线程没有立即准备好执行代码,要么只是你可能有单核机器并且主线程占用 cpu,然后其他线程必须等到分配给主线程的 cpu 时间片结束。 为了在您的程序执行中实现微小的确定性,您可以将Thread.sleep(100)放在主循环中以为其他线程运行创造机会。 那应该改变执行顺序。

如果我正确理解任务,那么买家和卖家应该在一天结束之前进行一些交易,然后新的一天应该开始(而不是更早)。

如果是这样,那么在这里使用Thread.sleep是不好的解决方案,原因有两个

  1. 如果您设置了短暂的延迟,那么新的一天可能会在交易尚未完成时开始
  2. 如果你设置了很长的延迟(在真实的生产环境中,确定足够长的时间来涵盖所有可能的未来场景是一项艰巨的任务)那么在大多数情况下你会浪费线程(*)+你的代码可能会很慢

正确的解决方案不是猜测交易是否完成,而是等待“所有交易都完成”事件。

它可以通过多种方式实现(CountDownLatch、原子计数器等),但最简单的方法是等待一天开始的所有线程都停止


while (day <= 30){
       System.out.println("Day " + day + " beginning. There are " + carShowroom.getCars().size()  + " cars in the showroom today.");

        int randomSeller = rand.nextInt(3);
        int randomBuyer = rand.nextInt(3);

        List<Thread> allThreads = new List<>(randomSeller+randomBuyer+2);

        for (int j = 0; j <= randomSeller; j++){
            Seller seller = new Seller(carShowroom);
            Thread mySellerThread = new Thread(seller);
            mySellerThread.start();
            allThreads.add(mySellerThread);
        }

        for (int i = 0; i <= randomBuyer; i++){
            Buyer buyer = new Buyer(carShowroom);
            Thread myBuyerThread = new Thread(buyer);
            myBuyerThread.start();
            allThreads.add(myBuyerThread);
        }

        for (Thread t : allThreads) {
          t.join();
        }

        // "all deals are done"

        day++;
    }

t.join导致主线程(循环几天)等待线程完成(== seller.run()buyer.run()方法完成)。 如果线程已经完成,那么t.join也是安全的,它会退出。

一旦您确认所有卖家和买家线程都已完成,您就知道“所有交易都已完成”

(*) 例如,如果您的 days 循环是在从池中获取的线程中执行的,那么当您正在执行sleep线程时,它不会执行任何工作,也不能用于任何其他任务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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