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在類對象上使用類實例作為監視器。類對象實際上是一個單例(在運行時代表類元數據的對象),并且這個塊中只能有一個線程。
添加回答
舉報