使用ExecutorService保留计数器



我想保留一个已执行线程的计数器,以便在我正在执行的相同线程中使用。

这里的问题是,尽管计数器增加了,但它增加的不均匀,从控制台输出中我得到了这个(我有一个使用 ExecutorService 执行 5 个线程的 for 循环(:

This is a test. N:3
This is a test. N:4
This is a test. N:4
This is a test. N:4
This is a test. N:4

如您所见,我没有1,2,3,4,5而是3,4,4,4,4.

我认为这是因为 for 循环的运行速度足以执行线程,并且线程足够快,可以执行请求计数器的代码,速度比计数器本身更新的速度快(这甚至有意义吗?

这是代码(它更小,计数器没有有意义的用途(:

for (int i = 0; i  <  5; i++)
{
Thread thread;
thread = new Thread()
    {
        public void run()
            {

                System.out.println("This is test. N: "+aldo );
                //In here there is much more stuff, saying it because it might slow down the execution (if that is the culprit?)
                return;
            }
    };
threadList.add(thread);
}
//later
for (int i = 0; i < threadList.size(); i++)
{
executor.execute(threadList.get(i));
aldo = aldo + 1;
}
executor.shutdown();
try
{
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException e)
{
}

是的,aldo代码中缺少计数器(我认为还有其他一些列表((它们非常简单(。

我知道这样做

的最好方法是创建一个带有传入数字的构造函数的自定义线程类。然后,保存数字的变量稍后可用于任何所需的日志记录。这是我想出的代码。

public static void main(String[] args) {
    class NumberedThread implements Runnable {
        private final int number;
        public NumberedThread(int number) {
            this.number = number;
        }
        @Override
        public void run() {
            System.out.println("This is test. N: " + number);
        }
    }
    List<Thread> threadList = new ArrayList<>();
    for (int i = 1; i  <  6; i++) threadList.add(new Thread(new NumberedThread(i)));
    ExecutorService executor = Executors.newFixedThreadPool(10);;
    for (Thread thread : threadList) executor.execute(thread);
    executor.shutdown();
    try {
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    }
    catch (InterruptedException ignored) { }
}

如果要命名线程,也可以改用字符串对象。

aldo不是由线程中的任务修改的,而是在主线程中修改的,如下所示:

for (int i = 0; i < threadList.size(); i++) {
    executor.execute(threadList.get(i));
    //here...
    aldo = aldo + 1;
}

此外,由于您想要一个可以在多个线程中增加其值的计数器,因此您可以使用 AtomicInteger 而不是 int .

您的代码应如下所示:

AtomicInteger aldo = new AtomicInteger(1);
for (int i = 0; i < 5; i++) {
    executor.execute( () -> {
        System.out.println("This is test. N: " + aldo.getAndIncrement());
    });
}

相关内容

  • 没有找到相关文章

最新更新