我在我的应用程序中使用ScheduledExecutorService.我需要在某个Utility类中不时使用它来运行计划的线程.
在静态字段中保存ScheduledExecutorService是一个好的设计吗?在这种情况下是否必须调用ScheduledExecutorService.shutdown()?如果我不调用关机会有什么风险?
这就是我的想法:
private static ScheduledExecutorService exec = Executors.newScheduledThreadPool(5);
public void scheduleTask(String name) {
Future<?> future = futuresMapping.get(name);
if(future!=null && !future.isDone())
future.cancel(true);
//execute once
Future<?> f = scheduledExecutor.schedule(new MyTask()), 1, TimeUnit.MINUTES);
futuresMapping.put(name, f);
}
Run Code Online (Sandbox Code Playgroud)
谢谢
好的,所以我知道这里的第一个答案/评论将是"使用一个ExecutorService并使用invokeAll".但是,有一个很好的理由(我不会让人厌烦)让我们保持线程池分离.
所以我有一个线程池(ExecutorServices)列表,我需要做的是Callable在每个线程池上调用一个不同的submit(没有问题).现在我有了这个Future实例集合,每个实例都是单独创建的ExecutorService,我想等待所有这些实例完成(并且能够提供一个超时,任何未完成的操作都会被取消).
是否存在将执行此操作的现有类(包装Future实例列表并允许等待直到完成所有操作)?如果没有,将赞赏有效机制的建议.
正在考虑get为每个呼叫设置超时,但必须计算每次呼叫的总时间.
我看到这篇帖子等到任何未来完成但这延伸Future而不是包装它们的列表.
我试图通过执行程序和runnable并行执行100个任务,任务需要使用循环变量:
for (int i = 0; i < 100; i++) {
executor.execute(() -> {
doSomething(String.format("Need task number %d done", i));
}
});
}
Run Code Online (Sandbox Code Playgroud)
在'我'说的时候,我得到一个波浪形的 - Variable used in lambda expression should be effectively final.
据我所知,循环变量不能是最终的或有效的最终变量,因为它随着每次迭代而被更改.我发现了一个简单的解决方法,
for (int i = 0; i < 100; i++) {
int index = i;
executor.execute(() -> {
doSomething(String.format("Need task number %d done", index));
}
});
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎不是最有效的解决方案,在每次迭代时声明一个新变量.有没有更好的方法呢?
我将Futures从ExecutorService推送到哈希映射中.之后,我可以在哈希映射中调用取消期货.虽然结果是正确的,但我后来在Callable过程中命中了断点,好像Future cancel()没有效果.我认为这可能是两个不同引用的情况(即使引用ID在断点时被列为相同),但是想知道某些专家是否可以插入.这是代码的样子:
ExecutorService taskExecutor = Executors.newCachedThreadPool();
Map <String, Future<Object>> results = new HashMap <String, Future<Object>>();
Future<Object> future = taskExecutor.submit(new MyProcessor(uid));
results.put(uid, future);
Run Code Online (Sandbox Code Playgroud)
我允许继续处理(这是一个在传入任务时提交任务的循环),稍后我可能会尝试通过调用此方法从外部源取消:
public static synchronized boolean cancelThread(String uid) {
Future<Object> future = results.get(uid);
boolean success = false;
if (future != null) {
success = (future.isDone() ? true : future.cancel(true));
if (success)
results.remove(uid);
}
return success;
}
Run Code Online (Sandbox Code Playgroud)
但是在调用future.cancel()之后,我仍然在MyProcessor.call()中遇到"未取消"路径 - 即它并没有真正被取消.
我哪里错了?这样做有好处吗?
我提出了以下问题:出于性能原因,我需要跨多个线程拆分工作,但我不确定采取什么方法.
首先,我将提供的任务应该返回一个值并获取一个参数.另外,主要方法(做主要工作,而不是static main())已经在单独的线程上运行,并定期调用.此外,此方法必须在某个时刻等待所有线程完成然后继续.
一种方法(对我来说最明显)是将每个作业安排在一个单独的线程上并将结果存储在类变量中:
public Object result1, result2;
public void mainMethod() throws InterruptedException {
final Thread thread = new Thread(new Runnable() {
@Override
public void run() {
result1 = expensiveMethod("param1");
}
});
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
result2 = expensiveMethod("param2");
}
});
thread1.join();
thread.join();
//Do rest of work
}
private Object expensiveMethod(Object param){
// Do work and return result
}
Run Code Online (Sandbox Code Playgroud)
这有点难看并且不太理想,因为正如我所说,mainMethod被多次调用,我不希望在设置结果变量时有任何竞争条件.理想情况下,我想让它们成为局部变量,但我不能在run方法中访问它们,除非它们是final,然后我不能为它们赋值......
另一种方法,我虽然这样做是这样的:
public void mainMethod() throws InterruptedException, ExecutionException {
String …Run Code Online (Sandbox Code Playgroud) 我是多线程的新手,我正在开发一个项目,我试图在我的Java程序中使用4个CPU.我想做点什么
int numProcessors = Runtime.getRuntime().availableProcessors();
ExecutorService e = Executors.newFixedThreadPool(numProcessors);
Run Code Online (Sandbox Code Playgroud)
这可以保证每个CPU都有一个线程工作吗?在我创建线程时,系统不会很忙,但是一段时间后它会非常繁忙.我认为操作系统会选择最不繁忙的CPU来创建线程,但是如果它们在创建时没有特别繁忙的话它是如何工作的呢?
此外,线程池服务应该重用线程,但如果它看到另一个CPU上有更多的可用性,它会杀死线程并在那里产生一个新线程吗?
我正在使用Guava的ListenableFuture,关于它们的一个好处是将Executor传递给Futures.addCallback方法,即要求在给定的线程/执行器上执行回调.
在我的Android应用程序中,我希望能够基于ListenableFutureUI线程启动异步执行,并安排一个也在UI线程上执行的回调.因此,我想以某种方式将UI线程执行器提交给Futures.addCallback上面提到的方法.怎么实现呢?
或者,换句话说,我想拥有UI线程的执行程序.它是否已经在Android中可用,或者,如果我必须创建自己的,我该怎么做?
编辑:作为这个问题的扩展,是否有可能做同样的事情,但不只是与UI线程,但与任何特定的线程,在哪里调用异步方法?
我会很高兴知道如何达到同样的效果,而不诉诸Android相关的东西像Handler和Looper,只需用纯Java.
我正在使用asyncTasks,用图像加载列表元素(只需按照android的有效加载位图的教程)
在DDMS中,我可以看到最多5个AsyncTasks正在运行
此外,我还添加了另一个AsyncTask,它使用MediaCodec类执行一些解码.
现在在DDMS中,我仍然看到5个AsyncTasks,我的图像加载aynctask或解码异步任务执行,而不是两个.
当解码正在运行时,如果我滚动列表,元素的图像不会更新当我通过调用它的执行方法启动新的解码asynctask时,解码不会启动,但如果我现在滚动列表视图,图像会更新.
那么AsyncTask是否有限制?
即使在listAdapter中,我也会根据getView调用启动AsyncTask.我期待7个运行asyncTasks(如果列表可见元素是7,比方说),但DDMS只显示5个asynctasks正在运行.
现在有人可以解释一下我无法拼写的黑魔法是什么吗?
android executorservice android-asynctask threadpoolexecutor
我想在整个应用程序中使用相同的线程池.为此,我可以让ExecutorService静态和全局,这样我可以调用ThreadUtil.executorService得到ExecutorService,当我需要它.
public class ThreadUtil {
public static final ExecutorService executorService = Executors.newCachedThreadPool();
}
Run Code Online (Sandbox Code Playgroud)
可以像这样实例化多个线程池吗?
另外,我的应用程序是TCP服务器.如果我不知道游泳池应该有多大,可以简单地使用newCachedThreadPool吗?
我在我的多线程应用程序中使用了Java Executors,但我似乎无法弄清楚何时最好使用以下各种方法:
1.
ExecutorService executor=Executors.newFixedThreadPool(50);
executor.execute(new A_Runner(... some parameter ...));
executor.shutdown();
while (!executor.isTerminated()) { Thread.sleep(100); }
Run Code Online (Sandbox Code Playgroud)
2.
int Page_Count=200;
ExecutorService executor=Executors.newFixedThreadPool(50);
doneSignal=new CountDownLatch(Page_Count);
for (int i=0;i<Page_Count;i++) executor.execute(new A_Runner(doneSignal, ... some parameter ...));
doneSignal.await();
executor.shutdown();
while (!executor.isTerminated()) { Thread.sleep(100); }
Run Code Online (Sandbox Code Playgroud)
3.
int Executor_Count=30;
ThreadPoolExecutor executor=new ThreadPoolExecutor(Executor_Count,Executor_Count*2,1,TimeUnit.SECONDS,new LinkedBlockingQueue());
List<Future<String>> futures=new ArrayList<>(3330);
for (int i=0;i<50;i++) futures.add(executor.submit(new A_Runner(... some parameter ...));
executor.shutdown();
while (!executor.isTerminated()) { executor.awaitTermination(1,TimeUnit.SECONDS); }
for (Future<String> future : futures)
{
String f=future.get();
// ...
}
Run Code Online (Sandbox Code Playgroud)
具体来说,在[2]中,如果我跳过doneSignal,那么它就像[1],那么doneSignal的用途是什么?
另外,在[3]中,如果我添加一个doneSignal怎么办?或者有可能吗?
我想知道的是:这些方法是否可以互换,或者是否存在我应该使用上述特定类型的某种情况?
java multithreading executorservice java.util.concurrent threadpoolexecutor
executorservice ×10
java ×9
android ×2
concurrency ×2
future ×2
threadpool ×2
final ×1
guava ×1
lambda ×1