亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

創建新對象后控制方法調用的調用

創建新對象后控制方法調用的調用

LEATH 2021-12-01 19:54:39
我有一個預定的方法調用,它在預定的時間調用以下方法:private void doSomething(Map<String, String> someArguments) throws CustomException {  MyEnum runType = getRunType(someArguments);  switch (runType) {        case FRUIT:             new FruitClass().workNow();             break;        case VEGETABLE:             new VegetableClass().workNow();             break;        default:            // log that the type is not known       }   }的方法簽名workNow是這樣的:workNow() throws CustomExceptionworkNow方法運行幾分鐘并做一些工作。我的問題是,當一個workNowfor FRUIT(or VEGETABLE) 正在進行并且另一個調用發生在相同類型(FRUIT例如)時,它會創建一個新FruitClass實例并開始workNow并行執行它。我如何控制這種行為?我希望通過第二個對象的第二次調用等到第一個workNow到第一個對象未完成。澄清:并行調用FRUIT和VEGETABLE很好。我想控制相同類型的并行調用。兩個以上FRUIT或兩個以上VEGETABLE。我不能FruitClass和VegetableClass單身人士一樣。我需要一些包裝代碼來new按照我想要的方式工作。
查看完整描述

3 回答

?
PIPIONE

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 

        }

    }

}

兩者都在一個略有不同的示例中進行了測試,但要說明這一點。


查看完整回答
反對 回復 2021-12-01
?
瀟湘沐

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 個相同類型的任務。


它提供了異步執行的額外好處,盡管您可以在需要時顯式阻塞以等待結果。


查看完整回答
反對 回復 2021-12-01
?
慕標5832272

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


查看完整回答
反對 回復 2021-12-01
  • 3 回答
  • 0 關注
  • 238 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號