源码|newTaskFor()和适配器模式

AbstractExecutorService提供了一个创建任务的工厂方法——newTaskFor()。工厂方法大家很熟悉了,但newTaskFor()中用到的适配器模式却少有人提到。

JDK版本:oracle java 1.8.0_102

高能预警!这篇,又!短!又!没!用!

newTaskFor()和工厂方法模式

在AbstractExecutorService中,可以提交三种形式的task:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task, result);
    execute(ftask);
    return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}
复制代码

三种形式类似,主要区别在于工厂方法AbstractExecutorService#newTaskFor():

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}
复制代码

直接调用了FutureTask的有参构造函数。

FutureTask实现了RunnableFuture接口:

public class FutureTask<V> implements RunnableFuture<V> 
复制代码

该接口继承了Runnable、Future接口,并只有一个run方法。看下FutureTask的构造方法:

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}
复制代码

8行是一个适配器模式:

this.callable = Executors.callable(runnable, result);
复制代码

通过静态工厂方法兼适配器Executors.callable()将Runnbale实例和result适配为Callable实例。

callable()和适配器模式

public static <T> Callable<T> callable(Runnable task, T result) {
    if (task == null)
        throw new NullPointerException();
    return new RunnableAdapter<T>(task, result);
}
复制代码

RunnableAdapter完成实际的适配工作:

static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    RunnableAdapter(Runnable task, T result) {
        this.task = task;
        this.result = result;
    }
    public T call() {
        task.run();
        return result;
    }
}
复制代码

通过RunnableAdapter实例调用Callable#call()方法时,RunnableAdapter仅仅先调用Runnable#run(),再返回result。框架并没有什么地方会操作result——换句话说,这个适配器仅仅是让Runable实例能够被提交到ExecutorService中,与返回值并没有半分钱的关系

对,就是这么没用,但是用来讲适配器还是阔以的。

总结

通过AbstractExecutorService#newTaskFor()学习工厂方法模式,通过Executors.callable()学习适配器模式——嗯,,,虽然这个适配器没什么用。

另外,注意到AbstractExecutorService#newTaskFor()的访问权限为protected,我们可以在扩展类中覆写或直接使用该方法。如ForkJoinPool:

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
   return new ForkJoinTask.AdaptedRunnable<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
   return new ForkJoinTask.AdaptedCallable<T>(callable);
}
复制代码

适配器走起。


本文链接:源码|newTaskFor()和适配器模式
作者:猴子007
出处:monkeysayhi.github.io
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名及链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 源码中,适配器模式被广泛应用于 UI 层,特别是 ListView 和 RecyclerView 这样的列表控件中。 举例来说,ListView 和 RecyclerView 的数据源都是一个 Adapter 对象,该对象负责将数据绑定到列表中的视图上。Adapter 接口定义了一些方法,例如 getCount()、getItem() 和 getView() 等,用于获取数据总数、单个数据项和显示数据项对应的 View 视图。 具体来说,ListView 和 RecyclerView 会调用 Adapter 的 getCount() 方法获取数据总数,在绘制列表时会调用 getView() 方法获取每个数据项对应的 View 视图,并将数据绑定到视图上。如果数据源发生变化(例如添加或删除数据项),则需要调用 Adapter 的 notifyDataSetChanged() 方法通知列表控件重新绘制。 另外,RecyclerView 还引入了更高级的适配器模式,即 ViewHolder 模式。ViewHolder 模式可以减少 findViewById() 方法的调用次数,从而提高列表绘制的性能。在 ViewHolder 模式中,Adapter 会持有一个 ViewHolder 对象,该对象用于存储数据项的视图和相关信息。RecyclerView 在绘制列表时,会先检查 ViewHolder 是否已创建,如果已创建则直接使用该 ViewHolder 对象,否则会创建一个新的 ViewHolder 对象并绑定到数据项上。 因此,适配器模式在 Android 源码中起到了非常重要的作用,它使得列表控件的数据源和视图分离,提高了代码的可维护性和可重用性。同时,ViewHolder 模式更是提高了列表绘制的性能,优化了用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值