- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
最终目标是为 ListenableFuture 添加额外的行为s 基于 Callable
/Runnable
参数的类型。我想为每个 Future 添加额外的行为方法。 (示例用例可以在 AbstractExecutorService's javadoc 和 Goetz 的 Java Concurrency in Practice 的第 7.1.7 节中找到)
我有一个现有的 ExecutorService覆盖 newTaskFor .它测试参数的类型并创建 FutureTask
的子类。这自然支持提交以及 invokeAny和 invokeAll .
如何为 ListenableFuture 获得相同的效果由 ListeningExecutorService 返回?
换句话说,我可以把这段代码放在哪里
if (callable instanceof SomeClass) {
return new FutureTask<T>(callable) {
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("Canceling Task");
return super.cancel(mayInterruptIfRunning);
}
};
} else {
return new FutureTask<T>(callable);
}
这样我的客户端就可以执行 println
语句
ListeningExecutorService executor = ...;
Collection<Callable> callables = ImmutableSet.of(new SomeClass());
List<Future<?>> futures = executor.invokeAll(callables);
for (Future<?> future : futures) {
future.cancel(true);
}
这是我已经尝试过的事情的列表,以及为什么它们不起作用。
将 MyExecutorService
传递给 MoreExecutors.listeningDecorator .
问题 1: 不幸的是结果 ListeningExecutorService (AbstractListeningExecutorService
)不委托(delegate)给 ExecutorService方法,它委托(delegate)给 execute(Runnable) Executor 上的方法.因此,永远不会调用 MyExecutorService
上的 newTaskFor
方法。
问题 2: AbstractListeningExecutorService
通过我无法扩展的静态工厂方法创建 Runnable(一个 ListenableFutureTask)。
在 newTaskFor
中,正常创建 MyRunnableFuture
,然后用 ListenableFutureTask
包装它。
问题 1: ListenableFutureTask的工厂方法不接受 RunnableFuture s,它们接受 Runnable
和 Callable
。如果我将 MyRunnableFuture
作为 Runnable 传递,生成的 ListenableFutureTask
只会调用 run()
而不是任何 Future
方法(我的行为所在)。
问题 2: 即使它调用了我的 Future
方法,MyRunnableFuture
也不是 Callable
,所以当我创建 ListenableFutureTask
时,我必须提供一个返回值...我没有...因此是 Callable
。
让 MyRunnableFuture 扩展 ListenableFutureTask
而不是 FutureTask
问题: ListenableFutureTask
现在是最终的(从 r10/r11 开始)。
让 MyRunnableFuture
扩展 ForwardingListenableFuture并实现RunnableFuture .然后将 SomeClass
参数包装在 ListenableFutureTask
中,并从 delegate()
问题:挂起。我不太了解这个问题,无法解释它,但此配置会导致 FutureTask.Sync 中出现死锁。
源代码:根据要求,这是挂起的解决方案 D 的源代码:
import java.util.*;
import java.util.concurrent.*;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.*;
/** See http://stackoverflow.com/q/8931215/290943 */
public final class MyListeningExecutorServiceD extends ThreadPoolExecutor implements ListeningExecutorService {
// ===== Test Harness =====
private static interface SomeInterface {
public String getName();
}
private static class SomeClass implements SomeInterface, Callable<Void>, Runnable {
private final String name;
private SomeClass(String name) {
this.name = name;
}
public Void call() throws Exception {
System.out.println("SomeClass.call");
return null;
}
public void run() {
System.out.println("SomeClass.run");
}
public String getName() {
return name;
}
}
private static class MyListener implements FutureCallback<Void> {
public void onSuccess(Void result) {
System.out.println("MyListener.onSuccess");
}
public void onFailure(Throwable t) {
System.out.println("MyListener.onFailure");
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("Main.start");
SomeClass someClass = new SomeClass("Main.someClass");
ListeningExecutorService executor = new MyListeningExecutorServiceD();
Collection<Callable<Void>> callables = ImmutableSet.<Callable<Void>>of(someClass);
List<Future<Void>> futures = executor.invokeAll(callables);
for (Future<Void> future : futures) {
Futures.addCallback((ListenableFuture<Void>) future, new MyListener());
future.cancel(true);
}
System.out.println("Main.done");
}
// ===== Implementation =====
private static class MyRunnableFutureD<T> extends ForwardingListenableFuture<T> implements RunnableFuture<T> {
private final ListenableFuture<T> delegate;
private final SomeInterface someClass;
private MyRunnableFutureD(SomeInterface someClass, Runnable runnable, T value) {
assert someClass == runnable;
this.delegate = ListenableFutureTask.create(runnable, value);
this.someClass = someClass;
}
private MyRunnableFutureD(SomeClass someClass, Callable<T> callable) {
assert someClass == callable;
this.delegate = ListenableFutureTask.create(callable);
this.someClass = someClass;
}
@Override
protected ListenableFuture<T> delegate() {
return delegate;
}
public void run() {
System.out.println("MyRunnableFuture.run");
try {
delegate.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("MyRunnableFuture.cancel " + someClass.getName());
return super.cancel(mayInterruptIfRunning);
}
}
public MyListeningExecutorServiceD() {
// Same as Executors.newSingleThreadExecutor for now
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
if (runnable instanceof SomeClass) {
return new MyRunnableFutureD<T>((SomeClass) runnable, runnable, value);
} else {
return new FutureTask<T>(runnable, value);
}
}
@Override
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
if (callable instanceof SomeClass) {
return new MyRunnableFutureD<T>((SomeClass) callable, callable);
} else {
return new FutureTask<T>(callable);
}
}
/** Must override to supply co-variant return type */
@Override
public ListenableFuture<?> submit(Runnable task) {
return (ListenableFuture<?>) super.submit(task);
}
/** Must override to supply co-variant return type */
@Override
public <T> ListenableFuture<T> submit(Runnable task, T result) {
return (ListenableFuture<T>) super.submit(task, result);
}
/** Must override to supply co-variant return type */
@Override
public <T> ListenableFuture<T> submit(Callable<T> task) {
return (ListenableFuture<T>) super.submit(task);
}
}
最佳答案
基于这个问题和我最近进行的其他一些讨论,我得出的结论是 RunnableFuture
/FutureTask
本质上具有误导性:显然你提交一个 Runnable
,很明显你得到了一个 Future
,很明显底层的 Thread
需要一个 Runnable
。但是为什么一个类要同时实现 Runnable
和 Future
呢?如果是,它替换了哪个 Runnable
?这已经够糟糕了,但随后我们引入了多级执行器,事情就真的失控了。
如果这里有解决方案,我认为需要将 FutureTask
视为 AbstractExecutorService
的实现细节。我会专注于将问题分成两部分:
Future
。Runnable
/Future
区分。)(提示 Markdown 提示)
class MyWrapperExecutor extends ForwardingListeningExecutorService {
private final ExecutorService delegateExecutor;
@Override public <T> ListenableFuture<T> submit(Callable<T> task) {
if (callable instanceof SomeClass) {
// Modify and submit Callable (or just submit the original Callable):
ListenableFuture<T> delegateFuture =
delegateExecutor.submit(new MyCallable(callable));
// Modify Future:
return new MyWrapperFuture<T>(delegateFuture);
} else {
return delegateExecutor.submit(callable);
}
}
// etc.
}
这行得通吗?
关于java - 添加/扩展由 ListeningExecutorService 创建的 Future 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8931215/
前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理
所以我用 Create React App 创建并设置了一个大型 React 应用程序。最近我们开始使用 Storybook 来处理和创建组件。它很棒。但是,当我们尝试运行或构建应用程序时,我们不断遇
遵循我正在创建的控件的代码片段。这个控件用在不同的地方,变量也不同。 我正在尝试编写指令来清理代码,但在 {{}} 附近插入值时出现解析错误。 刚接触 Angular ,无法确定我错过了什么。请帮忙。
我正在尝试创建一个 image/jpeg jax-rs 提供程序类,它为我的基于 post rest 的 Web 服务创建一个图像。我无法制定请求来测试以下内容,最简单的测试方法是什么? @POST
我一直在 Windows 10 的模拟器中练习 c。后来我改用dev C++ IDE。当我在 C 中使用 FILE 时。创建的文件的名称为 test.txt ,而我给出了其他名称。请帮助解决它。 下面
当我们创建自定义 View 时,我们将 View 文件的所有者设置为自定义类,并使用 initWithFrame 或 initWithCode 对其进行实例化。 当我们创建 customUITable
我正在尝试为函数 * Producer 创建一个线程,但用于创建线程的行显示错误。我为这句话加了星标,但我无法弄清楚它出了什么问题...... #include #include #include
今天在做项目时,遇到了需要创建JavaScript对象的情况。所以Bing了一篇老外写的关于3种创建JavaScript对象的文章,看后跟着打了一遍代码。感觉方法挺好的,在这里与大家分享一下。 &
我正在阅读将查询字符串传递给 Amazon 的 S3 以进行身份验证的文档,但似乎无法理解 StringToSign 的创建和使用方式。我正在寻找一个具体示例来说明 (1) 如何构造 String
前言:我对 C# 中任务的底层实现不太了解,只了解它们的用法。为我在下面屠宰的任何东西道歉: 对于“我怎样才能开始一项任务但不等待它?”这个问题,我找不到一个好的答案。在 C# 中。更具体地说,即使任
我有一个由一些复杂的表达式生成的 ILookup。假设这是按姓氏查找人。 (在我们简单的世界模型中,姓氏在家庭中是唯一的) ILookup families; 现在我有两个对如何构建感兴趣的查询。 首
我试图创建一个 MSI,其中包含 和 exe。在 WIX 中使用了捆绑选项。这样做时出错。有人可以帮我解决这个问题。下面是代码: 错误 error LGH
在 Yii 中,Create 和 Update 通常使用相同的形式。因此,如果我在创建期间有电子邮件、密码、...other_fields...等字段,但我不想在更新期间专门显示电子邮件和密码字段,但
上周我一直在努力创建一个给定一行和一列的 QModelIndex。 或者,我会满足于在已经存在的 QModelIndex 中更改 row() 的值。 任何帮助,将不胜感激。 编辑: QModelInd
出于某种原因,这不起作用: const char * str_reset_command = "\r\nReset"; const char * str_config_command = "\r\nC
现在,我有以下由 original.df %.% group_by(Category) %.% tally() %.% arrange(desc(n)) 创建的 data.frame。 DF 5),
在今天之前,我使用/etc/vim/vimrc来配置我的vim设置。今天,我想到了创建.vimrc文件。所以,我用 touch .vimrc cat /etc/vim/vimrc > .vimrc 所
我可以创建一个 MKAnnotation,还是只读的?我有坐标,但我发现使用 setCooperative 手动创建 MKAnnotation 并不容易。 想法? 最佳答案 MKAnnotation
在以下代码中,第一个日志语句按预期显示小数,但第二个日志语句记录 NULL。我做错了什么? NSDictionary *entry = [[NSDictionary alloc] initWithOb
我正在使用与此类似的代码动态添加到数组; $arrayF[$f+1][$y][$x+1] = $value+1; 但是我在错误报告中收到了这个: undefined offset :1 问题:尝试创
我是一名优秀的程序员,十分优秀!