在Spring应用程序中等待线程完成

时间:2019-06-04 17:43:09

标签: java spring multithreading threadpoolexecutor

我正在使用Java Spring应用程序,并且实现了一个在应用程序启动后启动的线程,如下所示:

@Component
public class AppStartup implements ApplicationListener<ApplicationReadyEvent> {
    @Autowired
    private SomeService service;

    @Override
    public void onApplicationEvent(final ApplicationReadyEvent event) {
        service.executeAsyn();
    }
}

@Service
public class SomeService {
    private TaskExecutor taskExecutor;
    private ApplicationContext applicationContext;

    @Autowired
    private SomeService(TaskExecutor taskExecutor, ApplicationContext applicationContext) {
        this.taskExecutor = taskExecutor;
        this.applicationContext = applicationContext;
    }

    public void executeAsyn() {
        ResellerSyncThread myThread = applicationContext.getBean(MyThread.class);
        taskExecutor.execute(myThread);
    }

    public void methodToExecute() {
        //do something
    }
}

@Component
@Scope("prototype")
public class MyThread implements Runnable {
    @Autowired
    SomeService service;

    @Override
    public void run() {
        service.methodToExecute();
    }
}

本质上,我的目标是在应用程序启动后启动线程,其任务是运行一个方法(methodToexecute)并终止。这种方法似乎可行,并且比ThreadPool更简单,因为我只想要一个任务。

我的问题是如何等待线程启动,然后从主线程完成以进行一些验证。

来自主线程

public class SomeTest {
    @Test
    public void test() {
        //wait for thread to start

        //do something

        //wait for thread to finish

        //do something else

    }
}

请随时对我实现线程的方法发表评论。如果您有关于如何改进它的建议,这种方法的潜在问题等。

3 个答案:

答案 0 :(得分:1)

这可能与您的需求近似:在Thread类中添加一个标志,然后在main期间对其进行检查。

@Component
@Scope("prototype")
public class MyThread implements Runnable {
    @Autowired
    SomeService service;

    private static boolean done = false;

    public static boolean isDone() {
        return done;
    }

    @Override
    public void run() {
        service.methodToExecute();
        done = true;
    }
}

在主方法中:

public class SomeTest {
    @Test
    public void test() {
        //wait for thread to start

        //do something

        while(!MyThread.isDone())
             Thread.sleep(200); // or some other number you adjust

        //do something else

    }
}

*请注意,这仅在您仅运行一次executeAsyn()时有效,否则,您必须进行一些修改。

此解决方案有点肮脏,您可能可以通过更多的reasearch找到更干净的方法来完成所需的工作。

答案 1 :(得分:0)

以下是一些选项: 1.实现回调以在线程的开始/结束之前/之后触发 2.创建一个单独的线程,该线程正在读取静态标志,并设置该标志的另一个线程

但是,我不清楚为什么会使用它?

答案 2 :(得分:0)

由于需要按顺序执行2种方法,因此可以在Spring中使用@DependsOn批注。您可以将它们声明为bean,并且Spring保证如果bean A具有B的依赖关系,那么B将首先被初始化。因此bean“ firstMethod”的init方法“ initialize”必须做您需要的

  @Component
    public class Example{

        @Bean(initMethod = "init")
        @DependsOn("firstMethod")
        public void doSomethingElse() {
           //do something. Check flag if needed
        }

        @Bean(name = "firstMethod", initMethod = "initialize")
        public void doSomething() {
            //do something. 
        }

        //more methods
    }