多线程JAVA期间内存不足错误或程序无响应

多线程JAVA期间内存不足错误或程序无响应,java,multithreading,Java,Multithreading,我是多线程新手。字面上总体而言,我对Java还是相当陌生的。然而,我正在做一个模拟,线程似乎工作得很好,除了我偶尔会让程序变得没有响应,一旦它说内存不足错误。我想这是因为我创建了太多线程?在这一点上,它通常做到这一点,我有超过2000个线程在同一时间运行。我可以调整代码(即减少客户数量或增加滴答之间的时间)以释放系统的压力,但我想知道我是否可以做些什么来帮助减轻每个线程本身的负担。我很确定这不是死锁,因为如果我执行上面的操作,代码运行得很好,但是运行的时间更长,因此会有相同数量的客户通过。我将展

我是多线程新手。字面上总体而言,我对Java还是相当陌生的。然而,我正在做一个模拟,线程似乎工作得很好,除了我偶尔会让程序变得没有响应,一旦它说内存不足错误。我想这是因为我创建了太多线程?在这一点上,它通常做到这一点,我有超过2000个线程在同一时间运行。我可以调整代码(即减少客户数量或增加滴答之间的时间)以释放系统的压力,但我想知道我是否可以做些什么来帮助减轻每个线程本身的负担。我很确定这不是死锁,因为如果我执行上面的操作,代码运行得很好,但是运行的时间更长,因此会有相同数量的客户通过。我将展示代码的相关部分,如果需要更多,我很乐意将其张贴出来。请注意,我不太明白这一点,因此,一些非常简单和有益的解释将不胜感激,因为如果评论太复杂,我可能不知道如何实现它

这是创建线程的主类

    CheckoutFloor checkoutFloor = new CheckoutFloor();
    checkoutFloor.addCheckoutOperators(checkoutOperators);
    int tick = 0;
    int customers = 0;

    while (tick < simulationTime) {

        for (int i = 0; i < 2; i++) {
            Random rand = new Random();
            int random = rand.nextInt(100) + 1;
            if (random <= 50) {
                customerRunnable customer = new customerRunnable(checkoutFloor);
                Thread t = new Thread(customer);
                t.start();
                tick++;
            }
            else {
                tick++;
            } 
以下是相关的方法

public synchronized void addCustomer(Customer newCustomer) {
        customerList.add(newCustomer);
        System.out.println("no. of customers" + counter);
        counter++;
}


public synchronized CheckoutOperator weightedCheckoutDeterminator() {
    int totalCustomers = 0;
    int totalCustomersAdj = 0;
    for (int i = 0; i < checkoutOpList.size(); i++) {
        totalCustomers += getCheckoutOperator(i).getCustomerListLength();
    }
    if (totalCustomers == 0) {
        return getCheckoutOperator(0);
    } else {
        totalCustomersAdj = (checkoutOpList.size() * totalCustomers) - totalCustomers;
        int randomNumber = 0;
        try {
            randomNumber = new Random().nextInt(totalCustomersAdj) + 1;
        } catch (IllegalArgumentException ex) {
            return checkoutOpList.get(0);
        }

        for (int i = 0; i < checkoutOpList.size(); i++) {
            int operatorCustLength = (getCheckoutOperator(i).getCustomerListLength());

            if (randomNumber <= (totalCustomers - operatorCustLength)) {
                return getCheckoutOperator(i);

            } else {
                randomNumber = randomNumber - (totalCustomers - operatorCustLength);
            }
        }
        return checkoutOpList.get(0); //HOPEFULLY UNREACHABLE!!!

    }
公共同步作废添加客户(客户新客户){
customerList.add(新客户);
系统输出打印项次(“客户数量”+柜台);
计数器++;
}
公共同步签出运算符加权签出确定器(){
int totalCustomers=0;
int totalCustomersAdj=0;
对于(int i=0;i如果(randomNumber)“在正常情况下,我有超过2000个线程同时运行。”哦,天啊。好吧,这就是问题所在!我怀疑,所以我想我提出这个问题是为了确保这是我的问题,而不是别的什么。当我有2000个线程运行时,我真的把它通过了振铃器,它可能永远不会运行那么多。但我只是不喜欢这样的想法,如果有人更改了代码还是什么的?老实说,我不确定这是不是问题所在。这是你永远不应该做的事情,除非你真的有2000个处理顺序units@user3580294或者,如果每个线程都是非常受I/O限制的。根据经验,您的线程数不应该超过可用的处理单元限制生成的线程数时是否会发生OOM错误?
public synchronized void addCustomer(Customer newCustomer) {
        customerList.add(newCustomer);
        System.out.println("no. of customers" + counter);
        counter++;
}


public synchronized CheckoutOperator weightedCheckoutDeterminator() {
    int totalCustomers = 0;
    int totalCustomersAdj = 0;
    for (int i = 0; i < checkoutOpList.size(); i++) {
        totalCustomers += getCheckoutOperator(i).getCustomerListLength();
    }
    if (totalCustomers == 0) {
        return getCheckoutOperator(0);
    } else {
        totalCustomersAdj = (checkoutOpList.size() * totalCustomers) - totalCustomers;
        int randomNumber = 0;
        try {
            randomNumber = new Random().nextInt(totalCustomersAdj) + 1;
        } catch (IllegalArgumentException ex) {
            return checkoutOpList.get(0);
        }

        for (int i = 0; i < checkoutOpList.size(); i++) {
            int operatorCustLength = (getCheckoutOperator(i).getCustomerListLength());

            if (randomNumber <= (totalCustomers - operatorCustLength)) {
                return getCheckoutOperator(i);

            } else {
                randomNumber = randomNumber - (totalCustomers - operatorCustLength);
            }
        }
        return checkoutOpList.get(0); //HOPEFULLY UNREACHABLE!!!

    }