Make sure my code is thread safe

I use the Android service, which provides content to other applications that can register as a callback.

I am not 100% sure about how the Handler class for Android works, so can someone confirm that this code is thread safe?

public class MyService extends Service { private static final String MESSAGE = "message"; private final RemoteCallbackList<IMyCallback> readerCallbacks = new RemoteCallbackList<IMyCallback>(); private static final int REPORT_MSG = 1; private Thread readerThread; @Override public void onCreate() { readerThread = new Thread(readerRunnable); readerThread.setDaemon(true); readerThread.start(); } private Runnable readerRunnable = new Runnable() { @Override public void run() { while (!Thread.interrupted()) { // Blocking call byte[] message = JniCommunicator.readMessage(); if (message == null || message.length == 0) { continue; } Bundle b = new Bundle(); b.putByteArray(MESSAGE, message); Message m = readHandler.obtainMessage(REPORT_MSG); m.setData(b); readHandler.sendMessage(m); } } }; private final Handler readHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case REPORT_MSG: byte[] message = msg.getData().getByteArray(MESSAGE); // Broadcast the new message to all clients final int N = readerCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { readerCallbacks.getBroadcastItem(i).newMessage(message); } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // the dead object for us. } } readerCallbacks.finishBroadcast(); break; } } }; @Override public IBinder onBind(Intent intent) { return mBinder; } private final IService.Stub mBinder = new IService.Stub() { public void registerCallback(IMyCallback cb) { if (cb != null) readerCallbacks.register(cb); } public void unregisterCallback(IMyCallback cb) { if (cb != null) readerCallbacks.unregister(cb); } }; } 

In particular, if someone calls unregisterCallback () while the handler is in a for loop, will it fail?

From my point of view, the handler works in one thread, so it is thread safe, but I'm not sure.

thanks

+6
source share
1 answer

Handlers are thread safe, meaning their whole purpose.
I agree that the documentation on thread safety of handlers is not the best, but it would be very ironic if the class intended for communication between the thread was not thread safe.

About remote callbacks, they are also designed to provide thread safety, you should read the documentation about this, it clearly states:

It locks the base list of interfaces for working with multi-threaded incoming calls and a thread-safe way to iterate through a snapshot of the list without blocking it

All you have to do is that all variables with multiple access to the stream are thread safe (which they are in your case) and that they do not change (your final one, so no worries).

+5
source

Source: https://habr.com/ru/post/898781/


All Articles