这是我创建的用于管理仓库库存的基本应用程序。基本上五个线程或IT公司每个产生100个小部件,然后将其存储在仓库中。这很好,但偶尔会超过500的仓库限制。所以我想要五个独立的公司分别生产100个小部件并将它们存储在仓库中并停在500个小部件上。目前,它有时但并不总是超过限制。因此,如果我要运行它三次它将工作2/3并且它将继续向仓库添加一小部分小部件。所以我的问题是如何解决这个问题?
这是代码
public class mainClass {
public static void main(String[] args) {
warehouse acct1 = new warehouse(0); // create warehouse with nothing in it
System.out.print("Reciving widgets...");
acct1.checkBal();
manufacturer t1 = new manufacturer(acct1, "Calcutta"); // create 5 threads (manufacturers)
manufacturer t2 = new manufacturer(acct1, "New York");
manufacturer t3 = new manufacturer(acct1, "Chicargo");
manufacturer t4 = new manufacturer(acct1, "Liverpool");
manufacturer t5 = new manufacturer(acct1, "Tokyo");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
制造商类
import java.util.*;
public class manufacturer extends Thread {
warehouse myAcct; //class 'warehouse' assigned to variable MyAcct
String name;
int time;
Random r = new Random(); // imported from java.util this can be used to create a random amount of time
int amount = 100; // This variable is the manufacturing goal of each individual manufacture (thread)`
public manufacturer(warehouse acct, String x) {
myAcct = acct;
name = x; // name of the thread
time = r.nextInt(4000); // This creates the random time of anywhere between 0 and 9999
}
public void run() {
while (true) { // run forever
try {
sleep (time); // Create new widgets
} catch (InterruptedException e) { }
// 100 by each manufacturer
try{
Thread.sleep(time);
System.out.printf("%s has successfully manufactured %d widgets \n", name, amount);
//how long do u want to sleep for?
//System.out.printf("%s is done\n", name);
myAcct.adjustBal(100); System.out.println("widgets have been stored at the central warehouse");
System.out.println();
Thread.sleep(time);
}catch(Exception e){}
if (myAcct.getBal() == 500)
{
System.out.println("The target goal of 500 widgets have been created and delivered to the central warehouse");
System.exit(0);
//myAcct.adjustBal(100);// with 100 if necessary
}
}
}
}
public class warehouse {
int balance = 0;
public warehouse(int openingBal) { // constructor method
balance = openingBal;
}
public synchronized void adjustBal(int amt) {
balance += amt; // process a transaction
checkBal(); // then show the balance
}
public void checkBal() {
System.out.print (balance);
System.out.println();
}
public int getBal() {
return balance;
}
}
答案 0 :(得分:0)
这里有竞争条件:
if (myAcct.getBal() == 500)
{
System.out.println("The target goal of 500 widgets have been created and delivered to the central warehouse");
System.exit(0);
//myAcct.adjustBal(100);// with 100 if necessary
}
检查和System.exit(0)之间的另一个线程仍然可以在系统退出之前添加到仓库。
答案 1 :(得分:0)
您需要同步对共享变量balance
的读取和写入,以确保更改可见=>同时使getBalance()
同步。
但问题更可能是由于另一个答案中提到的竞争条件。
答案 2 :(得分:0)
您遇到的问题是由以下情况引起的:
假设您有400个项目,现在线程X正在添加另外100个。当线程X到达余额时检查if statement
另一个线程Y可能获得cpu时间并再添加100个(总共600个项目) )然后平衡检查永远不会通过。
您应该在adjustBalance
方法中进行限制检查,因为它是同步的,并确保只有一个线程添加一次检查限制。
一个非常重要的注意事项:使用System.exit(0)在中间中止您的进程是一个非常糟糕的编程。您应该阅读有关如何管理单个数据结构上的多个线程的生产者/消费者。