java里面的FutureTask简单使用(配合源码讲解)
来源:互联网 发布:战舰世界德克萨斯数据 编辑:程序博客网 时间:2024/06/05 20:14
最近无意间看到了关于AsyncTask
的一篇分析文章AsyncTask源码分析,记得很早之前还看过郭神博客里面分析了AsyncTask源码
。去查看AsyncTask
源码会发现里面使用了FutureTask
在它自己的构造函数里面,我的sdk
是android-23
里面查看的。
/** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ public AsyncTask() { // 这里注意它实现了Callable mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } }; // 这里使用了FutureTask mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { try { postResultIfNotInvoked(get()); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occurred while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } } }; }
其实这里把Callable
和FutureTask
2个比较重要的家伙弄懂,就能知道AsyncTask
大致是怎么实现的了。进入源码去看发现它们都是java提供的用来实现java并发编程的。
先具体看下Callable
的代码:
public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception;}
从代码注释很明显可以看出,是返回一个结果,那也表明我们可以在里面进行一些耗时操作之后(比如网络通信或者是数据库操作等等),然后在返回计算好之后的结果。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }// 这里在call里面doInBackground mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } };
可以看到WorkerRunnable
也是实现了Callable
,然后里面调用了doInBackground
。
然后我们再去看下FutureTask
代码:
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run();}
public interface Future<V> { /** * Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, has already been cancelled, * or could not be cancelled for some other reason. If successful, * and this task has not started when {@code cancel} is called, * this task should never run. If the task has already started, * then the {@code mayInterruptIfRunning} parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task. * * <p>After this method returns, subsequent calls to {@link #isDone} will * always return {@code true}. Subsequent calls to {@link #isCancelled} * will always return {@code true} if this method returned {@code true}. * * @param mayInterruptIfRunning {@code true} if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete * @return {@code false} if the task could not be cancelled, * typically because it has already completed normally; * {@code true} otherwise */ boolean cancel(boolean mayInterruptIfRunning); /** * Returns {@code true} if this task was cancelled before it completed * normally. * * @return {@code true} if this task was cancelled before it completed */ boolean isCancelled(); /** * Returns {@code true} if this task completed. * * Completion may be due to normal termination, an exception, or * cancellation -- in all of these cases, this method will return * {@code true}. * * @return {@code true} if this task completed */ boolean isDone(); /** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return the computed result * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an * exception * @throws InterruptedException if the current thread was interrupted * while waiting */ V get() throws InterruptedException, ExecutionException; /** * Waits if necessary for at most the given time for the computation * to complete, and then retrieves its result, if available. * * @param timeout the maximum time to wait * @param unit the time unit of the timeout argument * @return the computed result * @throws CancellationException if the computation was cancelled * @throws ExecutionException if the computation threw an * exception * @throws InterruptedException if the current thread was interrupted * while waiting * @throws TimeoutException if the wait timed out */ V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
代码不多,算是比较简单的吧。
为了深刻理解它具体的运用,那我们自己write simple(丧心病狂) code。
private static class RealData implements Callable<String> { @Override public String call() throws Exception { //这里是真实的业务逻辑,耗时很长 StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 10; i++) { stringBuffer.append(i); //模拟一段耗时操作 SystemClock.sleep(1 * 1000); } return stringBuffer.toString(); } } private void testCallable() { FutureTask<String> futureTask = new FutureTask<String>(new RealData()) { @Override protected void done() { //FutureTask执行完的回调 try { // FutureTask的get()是一个同步方法,会有时间等待,最好避免在主线程执行 String str = get(); System.out.println(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } doSomething(); } }; //自定义ExecutorService,我会在后面的文章中总结。 ExecutorService executor = Executors.newFixedThreadPool(1); //在这里执行RealData的call内容 executor.submit(futureTask); System.out.println(); } private void doSomething() { System.out.println(); /*执行回调结果*/ }
好了简单的示例代码写好了,在call
里面处理耗时并且返回结果,然后在done
里面通过get
拿到获取的结果,就可以利用Handler
通知主线程更新UI了。还记得AsyncTask
构造函数里面的代码么:
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } }; mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { try { postResultIfNotInvoked(get()); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occurred while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } } }; } private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } } private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
它也是在done
里面利用Handler
发送Message
去更新UI的。好了简单滴记录一下,今天就先这样吧!!!
1 0
- java里面的FutureTask简单使用(配合源码讲解)
- 源码探索系列15---那个AsyncTask里面的FutureTask
- java FutureTask 源码解析
- Java FutureTask 源码解析
- java-源码解读-FutureTask
- java FutureTask的简单用法示例
- 【JAVA】java中Future、FutureTask的使用
- java并发:FutureTask 和 CountDowmLatch 的使用
- Java 中的 Future 和 FutureTask 的使用
- Java源码阅读之FutureTask
- FutureTask、ExecutorService的使用
- FutureTask的使用
- FutureTask的使用示例
- FutureTask的使用
- ImageSwitcher配合Gallery的简单使用
- TabLayout配合viewpager的简单使用
- Retrofit和OkHttp的简单配合使用
- Log4j 配合 java 类的简单封装
- 游戏开发学习指导
- 错误笔记
- 深入剖析ThreadLocal
- 音视频框架ffmpeg源码的简要分析
- 随手一点小记录
- java里面的FutureTask简单使用(配合源码讲解)
- 企业怎样选择DOT认证机构?
- deferrable initially deferred
- Mybatis调用sqlserver2008存储过程
- 友情链接
- 4EC
- 深度学习中的非线性激励函数以及unsupervised pre-training
- IOS中可以一个多个xib文件对应一个类。当然也可以在一个Xib中创建多个view然后也是用一个类控制
- Kafka单机、集群模式安装详解(一)