下面是我的代码,买家和卖家与汽车和汽车展厅进行交互。据我所知,它的运行是应该的。但是,线程只能在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++;
}
}}
发布于 2022-02-14 23:57:27
我认为您的循环执行速度可能比Thread.start()的启动速度要快。
发布于 2022-02-14 23:58:19
这要么是由于生成的线程没有立即准备好执行代码,要么是因为您可能有单个核心计算机,而主线程占用cpu,那么其他线程必须等到分配给主线程结束的cpu时间片。为了在程序执行中实现极小的确定性,您可以将Thread.sleep(100)放在主循环中,为其他线程创建运行的机会。这应该会改变执行的顺序。
发布于 2022-02-23 15:00:00
如果我正确理解了任务,那么买卖双方应该在一天结束前做一些交易,然后新的一天应该开始(而不是更早)。
如果是这样,那么在这里使用Thread.sleep是一个糟糕的解决方案,原因有两个
如果您设置了较短的延迟,那么新的一天可能会从尚未完成交易的时候开始,如果您设置了长延迟(在实际的prod环境中,确定什么足够长以涵盖所有可能的未来场景),那么在大多数情况下,您将浪费线程(*) +您的代码可能是可见的慢速。
正确的解决办法将不是猜测交易是否完成,而是等待“所有交易都完成”。
它可以通过多种方式(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线程时不会执行任何工作,也不能用于任何其他任务。
https://stackoverflow.com/questions/71119460
复制相似问题