gpt4 book ai didi

java - 如何确保在java中并行处理中仅由一个线程执行代码块

转载 作者:行者123 更新时间:2023-12-03 13:23:30 25 4
gpt4 key购买 nike

我有一个使用 maven 命令行运行的测试类,如下所示:

public class TestRunner {

@org.junit.Test
public void testParallel() throws InterruptedException, ExecutionException {


//Takes 5 mins. Has 20 different tests with the tag @e2eDTC
Results DTC = Runner.path("classpath:").tags("@e2eDTC").reportDir("target/cucumber-html-
reports").parallel(1);
assertTrue(DTC.getErrorMessages(), DTC.getFailCount() == 0);
generateReport(DTC.getReportDir());

// Takes 4 min. Has 25 different tests the tag @e2eWNG
Results WNG = Runner.path("classpath:").tags("@e2eWNG").reportDir("target/cucumber-html-
reports").parallel(1);
assertTrue(WNG.getErrorMessages(), WNG.getFailCount() == 0);
generateReport(WNG.getReportDir());

// Takes 3 min. Has 18 different tests with the tag @e2eFFD
Results FFD = Runner.path("classpath:").tags("@e2eFFD").reportDir("target/cucumber-html-
reports").parallel(1);
assertTrue(FFD.getErrorMessages(), FFD.getFailCount() == 0);
generateReport(FFD.getReportDir());

}
}

上面的代码显然是连续的,需要 12 分钟多一点。 .我希望引入并行性,使得带有 3 行结果对象、断言和生成或报告的每个代码块(带有特定标记)都由单个线程并行运行。所以理论上总的处理时间会超过 5 分钟。这意味着带有 DTC 的 block 在线程上运行,WNG block 在不同线程上运行,FFD block 在单独线程上运行。在每个 block 内只有一个线程是可以的。

我尝试使用执行器服务,这是代码
public class TestRunner {

@org.junit.Test
public void testParallel() throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(3);

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new Callable<String>() {
public String call() throws Exception {
Results DTC = Runner.path("classpath:").tags("@e2eDTC").reportDir("target/cucumber-html-reports").parallel(1);
assertTrue(DTC.getErrorMessages(), DTC.getFailCount() == 0);
generateReport(DTC.getReportDir());
return "DTC Success";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
Results WNG = Runner.path("classpath:").tags("@e2eWarnings").reportDir("target/cucumber-html-reports").parallel(1);
assertTrue(WNG.getErrorMessages(), WNG.getFailCount() == 0);
generateReport(WNG.getReportDir());
return "WNG Success";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
Results FFD = Runner.path("classpath:").tags("@e2eFFD").reportDir("target/cucumber-html-reports").parallel(1);
assertTrue(FFD.getErrorMessages(), FFD.getFailCount() == 0);
generateReport(FFD.getReportDir());
return "FFD Success";
}
});
List<Future<String>> futures = executorService.invokeAll(callables);

for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}

executorService.shutdown();
}

然而,这给了我们 3 个线程,并且它随机地将线程分配给每个 block 内的多个测试并导致错误。

改变
ExecutorService executorService = Executors.newFixedThreadPool(3);


ExecutorService executorService = Executors.newSingleThreadExecutor()


再次使它成为一个顺序程序。
我希望将线程 1 分配给标签 @e2eDTC 并仅使用该标签运行测试,并且以相同的方式将线程 2 分配给 @e2eWNG,将线程 3 分配给 @e2eFFD。有可能有这样的设置吗?我不是 Java 开发人员,因此寻求一些关于如何实现这一目标的建议。这里也没有 main() 方法。

最佳答案

HashSet 不是线程安全的。您可以创建一个同步集

  Set<Callable<String>> callables = Collections.synchronizedSet(new HashSet<Callable<String>>());

或者你可以使用 ArrayList
 List<Callable<String>> tasksList = new ArrayList<Callable<String>>();

我认为您不需要执行程序池服务,因为您将无法控制,因为线程是由操作系统分配的。您可以使用以下代码
    public class ThreadTest {

@org.junit.Test
public void testFunc() {
ThreadTest test = new ThreadTest();

Thread a = new Thread(test.new DTC());
Thread b = new Thread(test.new WNG());
Thread c = new Thread(test.new FFD());

a.start();
b.start();
c.start();
}


class DTC implements Runnable {
@Override
public void run() {
try {
// Your logic
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("DTC Success " + Thread.currentThread().getName());
}
}

class WNG implements Runnable {
@Override
public void run() {
try {
// Your logic
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("WNG Success "+ Thread.currentThread().getName());
}
}

class FFD implements Runnable {
@Override
public void run() {
try {
// Your logic
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("FFD Success "+ Thread.currentThread().getName());
}
}

}

关于java - 如何确保在java中并行处理中仅由一个线程执行代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61983087/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com