当前位置: 首页 > 面试题库 >

@Async阻止线程继续执行,直到其他线程完成

国景铄
2023-03-14
问题内容

我有一个应用程序,在某些情况下需要计算某些次数。此计算功能具有@Async注释(来自Spring
Framework),可以在4个线程上运行这些计算。问题是我需要大约40000个这些计算,并且我想知道所有计算的开始和结束之间的时间,因此我看到在调用计算函数的for循环之前和之后的时间是什么。但是现在所有计算都放入队列中,因此for循环立即完成,时间大约为1秒,而计算要花几个小时才能完成。我尝试将最大队列大小设置为大约100(这也有助于减少内存使用),但这也不是解决方案,因为我将错过总花费的最后100次计算。

这是一些代码,它说明了相同的问题:

执行类:

public class Foo {
    public void executeBlaALotOfTimes() {
        long before = System.currentTimeMillis();

        for (int i = 0; i<40000; i++) {
            executeBla();
        }

        long after = System.currentTimeMillis();

        System.out.println("Time it took for a lot of bla to execute: " + (after - before) / 1000.0 + " seconds.");
    }
}

以及执行计算的类:

@Service
public class Bar {
    @Async
    public void executeBla() {
        System.out.println("Bla!");
    }
}

这将导致以下输出(假设Foo中的代码无限快速地执行):

bla执行大量时间:0.0秒。
布拉!
布拉!
布拉!
布拉!
。
。
。
等等

问题答案:

如果您需要等待执行完成,则可以返回a Future作为返回值,例如

@Async
public Future<Void> executeBla() {
    System.out.println("Bla!");
    return new AsyncResult<Void>(null);
}

这是人为的,因为没有返回实际值,但是它仍然允许调用代码等待所有执行完成:

public void executeBlaALotOfTimes() {
    long before = System.currentTimeMillis();

    Collection<Future<Void>> futures = new ArrayList<Future<Void>>();

    for (int i = 0; i<40000; i++) {
        futures.add(executeBla());
    }

    for (Future<Void> future : futures) {
        future.get();
    }

    long after = System.currentTimeMillis();

    System.out.println("Time it took for a lot of bla to execute: " + (after - before) / 1000.0 + " seconds.");
}

在这里,第一个循环触发异步任务并将期货存储在列表中。然后秒循环遍历期货,等待每一个期货结束。



 类似资料:
  • 我正在执行如下 shell 命令。 命令在执行完成之前不会转到下一条语句。我想要的是在后台执行它,即使对于Windows也是如此。 我试过了 它来到下一行,但不执行命令。

  • 我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我

  • 下面的代码片段执行两个线程,一个是每秒记录一次的简单计时器,第二个是执行remainder操作的无限循环: 这给出了以下结果:

  • 我正在编写一个Android应用程序,它连接到蓝牙设备,读取设备发送的数据,将其添加到AChartEngine图形中,并在文本视图中显示数据。 我的Bluetooth代码与BluetoothChat示例代码中的线程实现非常相似(它与SDK一起提供)。我可以在LogCat中看到< code>ConnectedThread循环正在执行并因此获得新数据,但我的TextView在7行之后停止更新,图形间歇

  • 我正在使用asynctask并行运行两个异步任务。executeOnExecutor(AsyncTask.THREAD\u POOL\u EXECUTOR) 。 让我们假设task1和task2并行运行,现在只有在task1和task2完成异常时才调用task3来运行。是否可以知道任务task1和task2何时完成工作?

  • 问题内容: 我下面有一段代码,该代码创建了几个线程来执行任务,而单独运行效果很好。但是,我很难理解为什么在所有线程完成并调用该语句之前,我在函数中调用的打印语句不会执行。我希望它们在线程执行时被调用。有没有简单的方法可以做到这一点,为什么首先要这样做呢? 问题答案: 这是由于stdout缓冲引起的。您仍然可以刷新缓冲区: 您可以在此处和此处找到有关此问题的更多信息。