JUnit在Java中使用静态变量运行线程

时间:2016-02-27 18:19:44

标签: java multithreading

我试图在JUnit中运行两个线程。以下代码将由多个JUnit测试调用。

我想在结果不为null时停止两个线程。我该怎么办?问题是多个JUnit测试共享相同的String结果对象,并且以前的测试会以某种方式阻止此代码。问题是当另一个测试调用此方法时,结果将赋值为null,而之前的测试将阻塞while(true)循环。

static String result = null;

public static synchronized String remoteClogTailDir(final int maxRetry, String hostName,
        final String identifier, final String remoteClogDirPaths, final String whichKeyValue) {

    result = null;
    final String[] hosts = hostName.split(",");
    if(hosts != null && hosts.length == 2){
        Thread t1 = null;
        Thread t2 = null;
        t1 = new Thread(new Runnable(){
            @Override
            public void run(){
                String resultOfThread = null;
                resultOfThread = remoteClogTailDir(maxRetry, hosts[0].trim(), identifier, null,
                        remoteClogDirPaths, false, whichKeyValue);
                if(result == null && resultOfThread != null){
                    result = resultOfThread;
                }
            }
        });

        t2 = new Thread(new Runnable(){
            @Override
            public void run(){
                String resultOfThread = null;
                resultOfThread = remoteClogTailDir(maxRetry, hosts[1].trim(), identifier, null,
                        remoteClogDirPaths, false, whichKeyValue);
                if(result == null && resultOfThread != null){
                    result = resultOfThread;
                }
            }
        });

        t1.start();
        t2.start();

        while(true){
            if(result != null){
                t1.interrupt();
                t2.interrupt();
                return result;
            }
        }
    }else{
        return remoteClogTailDir(maxRetry, hostName, identifier, null,
                remoteClogDirPaths, false, whichKeyValue);
    }
}

1 个答案:

答案 0 :(得分:0)

如果我理解正确,你想并行执行几次搜索,并完成第一次搜索。你不应该使用静态属性。

您可以使用ExecutorCompletionService执行此类任务:

Executor executor = Executors.newCachedThreadPool();
CompletionService<String> ecs = new ExecutorCompletionService<String>(executor);
List<Future<String>> futures = new ArrayList<Future<String>>();
try {
   futures.add(ecs.submit(search1));
   futures.add(ecs.submit(search2));

   for (int i = 0; i < futures.size(); ++i) {
     String result = ecs.take().get();
     if (result != null) {
       return result;
     }
   }
} finally {
  for (Future<String> f : futures) {
     f.cancel(true);
  }
}
executor.shutdownNow();

使用search1或search2一个简单的Callable:

Callable<String> search1 = new Callable<String() {
  public String call() {
    return remoteClogTailDir(...)
  }
}