簡體   English   中英

Android:在多線程服務中,LocalBroadcastManager安全嗎?

[英]Android: In a multi-threaded Service, is LocalBroadcastManager safe?

在多線程服務中是從不同線程調用的LocalBroadcastManager.getInstance(this).sendBroadcast() ,已經是線程安全的了嗎?

public class MyService extends Service
{
    // [...] define binder to allow access to doSomething() and doSomethingElse(), etc.

    @Override
    public IBinder onBind(Intent intent) 
    {
        return binder;
    }

    public void doSomething() 
    {               
        new Thread(new Runnable() 
        {           
             public void run() 
             {
                // [...] do something

                // TODO is this threadsafe??
                LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
                broadcastManager.sendBroadcast(new Intent(DONE_SOMETHING));
            }
        }).start();
    }

    public void doSomethingElse()
    {               
         new Thread(new Runnable() 
         {          
             public void run() 
             {
                 // [...] do something else

                 // TODO is this threadsafe??
                 LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
                 broadcastManager.sendBroadcast(new Intent(DONE_SOMETHING_ELSE));
            }
        }).start();
    }
}

LocalBroadcastManager.getInstance(this)對於相同的上下文實際上總是返回相同的實例,並且不會以其他方式進行同步,因此我實際上需要在LocalBroadcastManager周圍添加一個同步級別,如下所示:

MyService extends Service
{
    private class SyncedLocalBroadcastManager
    {       
        private LocalBroadcastManager broadcastManager;

        SyncedLocalBroadcastManager(LocalBroadcastManager manager)
        {
            broadcastManager = manager;
        }

        public synchronized void send(Intent intent)
        {
            broadcastManager.sendBroadcast(intent);
        }
    }

    private SyncedLocalBroadcastManager syncedBroadcastManager; 

    // [...] define binder to allow access to doSomething() and doSomethingElse(), etc.

    @Override
    public IBinder onBind(Intent intent) 
    {
        syncedBroadcastManager = new SyncedLocalBroadcastManager(LocalBroadcastManager.getInstance(this));

        return binder;
    }

    public void doSomething() 
    {               
        new Thread(new Runnable() 
        {           
             public void run() 
             {
                // [...] do something

                syncedBroadcastManager.send(new Intent(DONE_SOMETHING));
            }
        }).start();
    }

    public void doSomethingElse()
    {               
         new Thread(new Runnable() 
         {          
             public void run() 
             {
                 // [...] do something else

                 syncedBroadcastManager.send(new Intent(DONE_SOMETHING_ELSE));
            }
        }).start();
    }

}

還是有其他首選/規范的方式?

我不想在已經很復雜的結構中添加不必要的同步,但是找不到任何確認。

是的,它是線程安全的,這里是實際類getinstance mehtod的代碼片段:

public static LocalBroadcastManager getInstance(Context context) {
    synchronized (mLock) {
        if (mInstance == null) {
            mInstance = new LocalBroadcastManager(context.getApplicationContext());
        }
        return mInstance;
    }
}

因此,您可以使用它而沒有任何同步開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM