我的应用程序中有一个服务,该服务使客户端可以注册以接收来自该服务的回调.我尝试实现它,以便在调用客户端回调实现时,它们可以异步运行或在服务线程上按顺序运行.每个回调的具体行为取决于使用哪种方法注册客户端以进行回调.客户端可以向registerClIEntForCallbacks注册以使回调发生在主线程上,也可以向registerClIEntForAsyncCallbacks注册以使回调发生在新线程上.
我遇到的问题是,当我尝试在新线程上调用回调时,线程在thread.run()上阻塞,直到可运行项完成为止,从而有效地消除了我对多线程的尝试.我已经在下面发布了我的服务的代码(使用Javadoc,因为我知道它的时间很长).有人可以帮我理解为什么callAllRegisteredClIEnts中的线程无法同时运行吗?
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(); }}
解决方法:
您必须使用t.start()而不是t.run().
t.run()直接调用可运行对象的run()方法. t.start()启动一个新线程,然后调用run()方法.
另外,您应该考虑使用Executor而不是直接创建和启动线程…
总结以上是内存溢出为你收集整理的java-多线程回调方法全部内容,希望文章能够帮你解决java-多线程回调方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)