如何在 java 中为列表中的项目创建多个线程?

How to create multiple threads in java for items in a list?

我有一个订单列表:

订单

列出订单

我需要创建一个多线程数组(限制 8 个线程以便 cpu 不会过载),并为每个线程分配列表中的一个项目。

目前我正在做以下事情:

int limit = 8;
int size = orders.size();
j=0;

if(size <= 8) {
   limit = size;
} 

for(; j < size; j += 8) {
   Thread[] threads = new Thread[limit];

    for (; index < threads.length; index++) {
       threads[index] = new Thread(() -> {
           treatOrder(orders.get(j).getNUMBER());
       });
            
       j++;
       threads[index].start(); 
    }

    for (Thread thread : threads) {
            thread.join();
    }
}

问题是,如果我这样做,j 会递增,但它不会传递给线程,每个线程都会处理相同的顺序。

如何为每个要处理的线程传递订单号(不同)?

这是因为您在 lambda 中使用了 non-final 或 non-effectively-final 变量。 Lambda 表达式是 lexically scoped,这意味着它们不会引入新级别的范围,并且为了让它们使用外部声明的变量,它们必须是最终的或有效的最终的,因为 Java 创建了一个副本执行 lambda 表达式后这些变量。

您可以通过在包含订单号的循环中声明一个临时变量来修复您的代码:

int limit = 8;
        int size = orders.size();
        int j = 0;

        if (size <= 8) {
            limit = size;
        }

        for (; j < size; j += 8) {
            Thread[] threads = new Thread[limit];

            for (; index < threads.length; index++) {
                String orderNumber = orders.get(j).getNUMBER(); 
                threads[index] = new Thread(() -> {
                    treatOrder(orderNumber);
                });

                j++;
                threads[index].start();
            }

            for (Thread thread : threads) {
                thread.join();
            }
        }

注意:临时变量 必须 在循环内而不是在外部声明,因为这将使它成为有效的最终变量。这是因为在每次迭代时都会使用一个在其存在期间不会改变的常量值重新创建变量。