Android:在多线程服务中,LocalBroadcastManager安全吗?

时间:2015-03-10 15:49:39

标签: java android multithreading service

在多线程服务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();
    }

}

或者还有其他首选/规范方式吗?

我不想在已经很复杂的结构中添加不必要的同步,但我找不到任何确认。

1 个答案:

答案 0 :(得分:1)

是的,它是线程安全的,这里是来自实际类getinstance mehtod的代码片段:

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

因此,您可以在没有任何同步开销的情况下使用它。