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

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

在類構造函數中調用線程的替代方法

在類構造函數中調用線程的替代方法

慕工程0101907 2021-05-12 17:22:21
我有一個可以被多個線程訪問的類。我希望該類在響應調用(getSomething)之前先做一些事情。我當時想開始在類構造函數中啟動SampleThreadinside,但我不喜歡在構造函數中啟動線程的想法。我正在考慮做這樣的事情,但是我不確定這是否正確。將在類上調用getSomething的第一個線程將啟動一個線程。但是我仍然不確定這是否正確。。我擔心多個SampleThread會運行,而我只希望它運行一次。public class A{    private final AtomicBoolean isReady = new AtomicBoolean(false);    public A{    }    public void getSomething(){        if(!isReady.get()){            new SampleThread().start();        }        //continue with the rest of the method    }}public class SampleThread{    public void run(){        //Do some long running task once done        isReady.set(true);    }}我沒有辦法添加一個名為start()的方法,在該方法中我可以調用我的SampleThread,因為該方法是由框架調用的。有什么提示嗎?
查看完整描述

1 回答

?
小唯快跑啊

TA貢獻1863條經驗 獲得超2個贊

這種方式具有競爭條件:


public void getSomething(){

    if(!isReady.get()){

        new SampleThread().start();

    }

    //continue with the rest of the method

}

這是原子的: if(!isReady.get())但是與之關聯的條件語句的主體不是:


{

    new SampleThread().start();

}

因此,您可以啟動兩次該線程。


同步邏輯可防止出現競爭情況。這也將增加對象上潛在的鎖定數量,但是if(!isReady.get())應該快速執行,這應該是可以接受的。

請注意,AtomicBoolean如果布爾值僅在同步語句中使用,則可能不需要使用。


所以這里有兩種方式可以根據您的要求。


1)為了getSomething()開始第一次調用,SampleThread 并且其他線程在執行之前等待初始化結束getSomething():


public void getSomething(){

    synchronized(this){

      // init the logic 

      if(!isReady){

          SampleThread t = new SampleThread();

          t.start(); 

          t.join();  // wait for the SampleThread thread termination

          isReady.set(true);           

      }         

      // execute the next only as the init thread was terminated

      if(isReady){

         //continue with the rest of the method

      }


    }     

}

2)為了讓在第一次調用getSomething()開始SampleThread和別人線程不會等待此初始化執行前結束getSomething():


public void getSomething(){

    synchronized(this){

      // init the logic once

      if(!isReady.get()){

          SampleThread t = new SampleThread();

          t.start();                                   

      }                                   

    }

    //continue with the rest of the method       

}

并設置isReady以true在年底run()的SampleThread:


public void run(){

    //Do some long running task once done

    isReady.set(true);

}


查看完整回答
反對 回復 2021-05-26
  • 1 回答
  • 0 關注
  • 168 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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