Java multithreaded callback method

There is a service in my application that enables clients to register to receive callbacks from the service. I try to implement it so that when calling the client callback implementation, They can run asynchronously or sequentially on the service thread. The specific behavior of each callback depends on which method is used to register the client for callback. The client can register with registerclientforcallbacks to make the callback happen on the main thread, or register with registerclientforasynccallbacks to make the callback happen on a new thread

The problem I have encountered is that when I try to call the callback on a new thread, the thread blocks on thread. Run () until the runnable item is completed, which effectively eliminates my attempt to multithread. I have published the code of my service below (using Javadoc because I know it takes a long time) . can someone help me understand why the threads in callallregisteredclients cannot run at the same time?

public class ExampleService extends Service {
    /**
     * A record of the clients which have registered to receive callbacks from this service
     * asynchronously.
     */
    private Set<ClientCallbacks> registeredClientsAsync;

    /**
     * A record of the clients which have registered to receive callbacks from this service on the
     * service's main thread.
     */
    private Set<ClientCallbacks> registeredClientsMainThread;

    @Override
    public void onCreate() {
        super.onCreate();
        registeredClientsAsync = new HashSet<ClientCallbacks>();
        registeredClientsMainThread = new HashSet<ClientCallbacks>();
    }

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

    /**
     * A binder with the singular purpose of returning a reference to the service.
     */
    public class LocalBinder extends Binder {
        public ExampleService getService() {
            return ExampleService.this;
        }
    }

    /**
     * Register this client to receive callback events from this service. Callback methods will
     * execute sequentially on the service's main thread. Consider using {@link
     * #registerClientForAsyncCallbacks(ClientCallbacks) registerClientForAsyncCallbacks} for
     * asynchronous callbacks.
     *
     * @param client the client to register, not null
     * @return true if the client is unregistered or has been
     * registered to receive callbacks asynchronously using {@link
     * #registerClientForAsyncCallbacks(ClientCallbacks) registerClientForAsyncCallbacks}, false
     * otherwise
     */
    public boolean registerClientForCallbacks(@NonNull ClientCallbacks client) {
        if (client == null) {
            throw new IllegalArgumentException("client cannot be null");
        }

        // Attempt to remove from async callbacks set (may do nothing)
        registeredClientsAsync.remove(client);

        return registeredClientsMainThread.add(client);
    }

    /**
     * Register this client to receive callback events from this service. Callback methods will be
     * executed asynchronously on separate threads.
     *
     * @param client the client to register, not null
     * @return true if the client is unregistered or has been
     * registered to receive callbacks in the service's main thread using {@link
     * #registerClientForCallbacks(ClientCallbacks) registerClientForCallbacks}, false
     * otherwise
     */
    public boolean registerClientForAsyncCallbacks(@NonNull ClientCallbacks client) {
        if (client == null) {
            throw new IllegalArgumentException("client cannot be null");
        }

        // Attempt to remove from async callbacks set (may do nothing)
        registeredClientsMainThread.remove(client);

        return registeredClientsAsync.add(client);
    }

    /**
     * Calls the {@link #ClientCallbacks ClientCallbacks} callback methods in all registered
     * clients. Clients registered for asynchronous callbacks will execute immediately, and
     * clients registered for sequential callbacks will be called in turn. Note that if the
     * callback methods block, then the service's main thread will block.
     */
    private void callAllRegisteredClients() {
        // First start asynchronous callbacks
        for (ClientCallbacks client : registeredClientsAsync) {
            Thread t = new Thread(new CallbackRunnable(client), client.toString());
            t.run();
        }

        // Finally start sequential callbacks
        for (ClientCallbacks client : registeredClientsMainThread) {
            client.onServiceEvent(this);
        }
    }

    /**
     * Interface allows callback events to be delivered to registered server clients.
     */
    public interface ClientCallbacks {
        public void onServiceEvent(Service service);
    }

    /**
     * A utility class which allows client callback methods to be executed asynchronously.
     */
    private class CallbackRunnable implements Runnable {
        /**
         * The client to receive the callbacks.
         */
        private final ClientCallbacks client;

        /**
         * Creates a new CallbackRunnable.
         * @param client the client to receive the callback methods, not null
         */
        private CallbackRunnable(@NonNull ClientCallbacks client) {
            if (client == null) {
                throw new IllegalArgumentException("client cannot be null");
            }

            this.client = client;
        }

        @Override
        public void run() {
            android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
            client.onServiceEvent(ExampleService.this);
        }
    }

    /*
     * Testing
     * TODO remove
     */
    public void activateCallbacks() {
        callAllRegisteredClients();
    }
}

resolvent:

You must use t.start() instead of t.run()

T.run () directly calls the run () method of the runable object. T.start () starts a new thread and then calls the run () method.

In addition, you should consider using executor instead of directly creating and starting threads

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>