自定义 Runnables 而不是 Callables
检查我们的线程何时完成而不阻塞等待从 Callable 恢复 Future 对象的线程的另一个好习惯是为 Runnables 创建我们自己的实现,并将其与 execute()
方法一起使用。
在下一个示例中,我展示了一个使用内部回调实现 Runnable 的自定义类,允许我们知道 runnables 何时完成并稍后在 ThreadPool 中使用它:
public class CallbackTask implements Runnable {
private final Runnable mTask;
private final RunnableCallback mCallback;
public CallbackTask(Runnable task, RunnableCallback runnableCallback) {
this.mTask = task;
this.mCallback = runnableCallback;
}
public void run() {
long startRunnable = System.currentTimeMillis();
mTask.run();
mCallback.onRunnableComplete(startRunnable);
}
public interface RunnableCallback {
void onRunnableComplete(long runnableStartTime);
}
}
这是我们的 ThreadExecutor 实现:
public class ThreadExecutorExample implements ThreadExecutor {
private static String TAG = "ThreadExecutorExample";
public static final int THREADPOOL_SIZE = 4;
private long mSubmittedTasks;
private long mCompletedTasks;
private long mNotCompletedTasks;
private ThreadPoolExecutor mThreadPoolExecutor;
public ThreadExecutorExample() {
Log.i(TAG, "[ThreadExecutorImpl] Initializing ThreadExecutorImpl");
Log.i(TAG, "[ThreadExecutorImpl] current cores: " + Runtime.getRuntime().availableProcessors());
this.mThreadPoolExecutor =
(ThreadPoolExecutor) Executors.newFixedThreadPool(THREADPOOL_SIZE);
}
@Override
public void execute(Runnable runnable) {
try {
if (runnable == null) {
Log.e(TAG, "[execute] Runnable to execute cannot be null");
return;
}
Log.i(TAG, "[execute] Executing new Thread");
this.mThreadPoolExecutor.execute(new CallbackTask(runnable, new CallbackTask.RunnableCallback() {
@Override
public void onRunnableComplete(long RunnableStartTime) {
mSubmittedTasks = mThreadPoolExecutor.getTaskCount();
mCompletedTasks = mThreadPoolExecutor.getCompletedTaskCount();
mNotCompletedTasks = mSubmittedTasks - mCompletedTasks; // approximate
Log.i(TAG, "[execute] [onRunnableComplete] Runnable complete in " + (System.currentTimeMillis() - RunnableStartTime) + "ms");
Log.i(TAG, "[execute] [onRunnableComplete] Current threads working " + mNotCompletedTasks);
}
}));
}
catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "[execute] Error, shutDown the Executor");
this.mThreadPoolExecutor.shutdown();
}
}
}
/**
* Executor thread abstraction created to change the execution context from any thread from out ThreadExecutor.
*/
interface ThreadExecutor extends Executor {
void execute(Runnable runnable);
}
我做了这个例子来检查我的线程的速度,以毫秒为单位执行它们,而不使用 Future。你可以使用此示例并将其添加到你的应用程序以控制并发任务的工作,以及已完成/已完成的任务。检查所有时刻,执行该线程所需的时间。