3 回答
TA贡献1829条经验 获得超9个赞
几个解决方案,我能想到:
解决方案1
static final String FRUIT = "FRUIT";
static final String VEGETABLE = "VEGETABLE";
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
switch (runType) {
case FRUIT:
synchronized (FRUIT){
new FruitClass().workNow();
}
break;
case VEGETABLE:
synchronized (VEGETABLE){
new VegetableClass().workNow();
}
break;
default:
// log that the type is not known
}
}
这可能比使用class对象更好,因为它们会更重并消耗内存。
解决方案2
这是对解决方案 1 的增强,以防有多个案例并且String不需要类级别。
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
synchronized(runType.toString().intern()) {//This prevents 2 FRUITs or 2 VEGETABLEs from entering
switch (runType) {
case FRUIT:
new FruitClass().workNow();
break;
case VEGETABLE:
new VegetableClass().workNow();
break;
default:
// log that the type is not known
}
}
}
两者都在一个略有不同的示例中进行了测试,但要说明这一点。
TA贡献1816条经验 获得超6个赞
肯定有很多方法可以解决这个问题。我认为最简单的方法是为每种类型的任务使用单线程池:
//one pool per runType
private final ExecutorService fruitService = Executors.newSingleThreadExecutor();
private final ExecutorService vegService = Executors.newSingleThreadExecutor();
进而:
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
CompletableFuture<Void> result;
switch (runType) {
case FRUIT:
result = CompletableFuture.runAsync(() ->
new FruitClass().workNow(), fruitService)
.exceptionally((exception) -> {
if (exception instanceof CustomException) {
System.out.println("Failed with custom exception...");
}
return null; // returning Void
});
break;
case VEGETABLE:
result = CompletableFuture.runAsync(() ->
new VegetableClass().workNow(), vegService)
.exceptionally((exception) -> {
if (exception instanceof CustomException) {
System.out.println("Failed with custom exception...");
}
return null; // returning Void
});
break;
default:
throw new RuntimeException();
}
result.join();
}
这只是强制并发调用等待资源,并且不会同时运行 2 个相同类型的任务。
它提供了异步执行的额外好处,尽管您可以在需要时显式阻塞以等待结果。
TA贡献1966条经验 获得超4个赞
在类对象上进行同步,这足以避免在完成之前创建另一个类:
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
switch (runType) {
case FRUIT:
synchronized (FruitClass.class){
new FruitClass().workNow();
}
break;
case VEGETABLE:
synchronized (VegetableClass.class){
new VegetableClass().workNow();
}
break;
default:
// log that the type is not known
}
}
synchronized在类对象上使用类实例作为监视器。类对象实际上是一个单例(在运行时代表类元数据的对象),并且这个块中只能有一个线程。
添加回答
举报