我正在使用ExecutorService来调用一个服务,该服务基本上连接到一个应用程序(本地或通过 SSH 远程),并允许向其发送命令并获取其输出。
因此,Thread由 所创建的ExecutorService正在等待用户输入,然后通过 call 方法的实现将该输入作为任务处理,该方法返回输出,如下所示:
@Override
public String call() throws Exception {
write(command);
return readResult();
}
Run Code Online (Sandbox Code Playgroud)
当给定时间内没有调用任何任务时,我想停止Thread(关闭ExecutorService),但我找不到如何执行此操作...Future.get或者ExecutorService.invoke[All|Any]可以处理超时,但仅涉及它调用的任务。
关于我如何能够做到这一点有什么想法吗?
当我们使用Java的Executor服务创建一个线程池并向该线程池提交线程时,这些线程的执行顺序是什么?
我想确保线程先提交,先执行。例如,在下面的代码中,我希望首先执行前 5 个线程,然后执行接下来的 5 个线程,依此类推...
// Create a thread pool of 5 threads.
ScheduledExecutorService exService = Executors.newScheduledThreadPool(5, new ModifiedThreadFactory("ReadThreadPool"));
// Create 100 threads.
MyThread[] threads = createMyThreads(100);
// Submit these 100 threads to thread pool for execution.
for(MyThread thread : threads) {
exService.submit(thread);
}
Run Code Online (Sandbox Code Playgroud)
Java的线程池是否提供了用于此目的的API,或者我们是否需要在我们的末端实现一个FIFO队列来实现此目的。如果 Java 的线程池不提供任何此类功能,我真的很想了解此功能不存在背后的原因,因为它对我来说似乎是一个非常常见的用例。这在技术上是不可能的(我认为这不太可能),还是只是一个失误?
我使用单线程ScheduledExecutorService来处理一些Runnable任务。当我的Runnable工作完成后,它会以ScheduledExecutorService可变的延迟重新安排自己。这种情况会无限期地发生,直到Runnable捕获到Exception。
public class Runner {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
public void startWorking() {
// Single-shot start
service.submit(new Task(service));
}
public void stopWorking() {
service.shutDown();
// Do some other stuff
}
private static final class Task implements Runnable {
ScheduledExecutorService service;
private Task(ScheduledExecutorService service) {
this.service = service;
}
@Override
public void run() {
try {
// Do some work...
service.schedule(this, variableDelay, TimeUnit.SECONDS);
}
catch(SomethingHappenedException e){
// Shutdown service …Run Code Online (Sandbox Code Playgroud) 我有长时间运行的任务提交给ExecutorService. 该任务可能会运行相当长的时间。同时,新的任务被提交到内部阻塞队列。
提交的任务完成后,会发送回通知以从队列中释放任务以供执行。然而,有时,由于编程错误或网络问题,通知不会被触发。在这种情况下,我的任务队列可能会变得非常大,并且我可能会遇到任务可能永远留在队列中的情况。
为了克服这个问题,我正在考虑编写一个线程,该线程将定期检查任务在队列中空闲的时间。如果任务在队列中等待了 15 分钟,我会假设之前提交的任务遇到了错误,因此没有返回。然后我将从队列中逐出该任务并允许其执行。
是否有任何现有机制可以处理此问题,或者我必须编写此自定义逻辑?
注:
我不喜欢的原因ScheduledExecutor是因为并非所有任务都要定期执行。只有故障场景才应在一定延迟后执行。
编辑 架构的简要概述我正在设计的解决方案应该支持许多并发静态文件下载。通常可能有数千个下载请求。下载请求由基于 UI 的应用程序触发。这样我就知道何时会触发请求。利用这种方法,我打算限制下载请求。
当用户创建 300 个下载请求时会发生什么?
在我能够接收响应(HTTP 200/HTTP 500 等)的情况下,限制机制就像一个魅力。但是,例如,servlet 本身抛出异常,我没有收到任何响应来表明 HTTP 工作线程是空闲的。因此,该任务有可能永远保留在队列中。为了克服这个问题,我正在考虑一种基于计时器的方法,如果 15 分钟内没有 HTTP 响应,则提交下一个队列任务来执行。一种避免重大内存泄漏的回退机制。
我有一个 Spring @Configuration 类,如下所示:
@Configuration
public class ExecutorServiceConfiguration {
@Bean
public BlockingQueue<Runnable> queue() {
return ArrayBlockingQueue<>(1000);
}
@Bean
public ExecutorService executor(BlockingQueue<Runnable> queue) {
return ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, queue);
}
@PreDestroy
public void shutdownExecutor() {
// no executor instance
}
}
Run Code Online (Sandbox Code Playgroud)
我还想指定一种@PreDestroy关闭 ExecutorService 的方法。但是,该@PreDestroy方法不能有任何参数,这就是为什么我无法将executorbean 传递给该方法以关闭它的原因。指定 destroy 方法也@Bean(destroyMethod = "...")不起作用。它允许我指定现有的shutdownor shutdownNow,但不能指定我打算使用的自定义方法。
我知道我可以直接实例化队列和执行器,而不是作为 Spring bean,但我宁愿这样做。
首先是一点背景.我在NetBeans中收到警告告诉我不要在构造函数中启动新线程.我已经读过它的原因是因为新线程可能会启动并尝试在构造函数实际完成对象之前引用启动线程的对象.
1.)为了实验而不是使用new Thread和thread.start()我试过ExecutorService,我没有得到任何警告. 这是否意味着如果我使用的话,可以在构造函数中创建和启动新线程ExecutorService?
2.)另外,如果我有ExecutorService一个缓存线程池的形式将通过标准方法创建一个新线程new Thread并thread.start()从缓存池中拉出一个线程(或者如果一个线程不可用则导致它创建一个)或者这些线程是否完全独立于缓存的线程池?
我有一个要处理的事件队列.线程将事件添加到队列中.
我创建了一个可运行的Task,在该run方法中执行处理事件所需的所有操作.
我已经宣布了Executors.newCachedThreadPool();我和execute每个任务.
public class EventHandler {
private static final ExecutorService handlers = Executors.newCachedThreadPool();
public void handleNextEvent(AnEvent event){
handlers.execute(new Task(evt));
}
public class Task implements Runnable{
@Override
public void run() {
//Event processing
}
}
public AnotherClass{
public void passEvent(AnEvent evt)//This is called by another thread
{
EventHandler.handleNextEvent(evt);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我调用execute执行程序,我的代码将获得下一个事件并通过执行程序运行下一个runnable.我的目的是仅在上一个任务结束后才从队列中处理下一个事件.
我怎么知道前一个任务已经完成,所以我知道我可以再次调用handleNextEvent?
是否有一个状态字段由任务更新一个好主意?
谢谢
我遇到了可调用线程的问题.
这是代码snipet:
ExecutorService service = Executors.newFixedThreadPool(1);
for(int i =0; i<30;i++){
Future<MyClass> task = service.submit( new MyThread(parameter1, parameter2));
try{
result = task.get();
}
catch(InterruptedException ex){
System.out.println("Interruped!");
}
catch(ExecutionException ex){
System.out.println("Execution ExceptioN!");
}
}
service.shutdownNow();
Run Code Online (Sandbox Code Playgroud)
上面的代码将正确执行18次,然后在第18次之后抛出ExecutionException.
我究竟做错了什么?
谢谢!
我正在创建15个可调用任务,并提交它们:
List<Future<MyResult>> futures = new ArrayList<Future<MyResult>>();
List<MyResult> myResults = new ArrayList<MyResult>();
for(int i = 1; i <= 15; i++){
Callable<MyResult> task = new MyProcessor(//parameters);
Future<MyResult> future = executorService.submit(task);
futures.add(future);//used to iterate over to call get() to collect results in next for loop
}
Run Code Online (Sandbox Code Playgroud)
然后我收集了15个MyResult对象:
for(Future<MyResult> future : futures){
try {
MyResult myResult = future.get();
processorResults.add(myResult);
} catch (InterruptedException e) {
//...
} catch (ExecutionException e) {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
问题是:不是从get()方法返回所有15个MyResult对象,我有时会得到少于15个对象.有时12有时10有时甚至更小,有时甚至15.
我的印象是,get()方法是一个阻塞调用,并且将等待所有15个线程返回相应的结果,但看起来我错过了其中一些并继续前进.我做错了什么?我没有收集结果/正确等待结果?当从任何MyProcessor任务抛出ERROR时会发生这种情况吗?
在AWS Lambda中建议使用执行程序服务吗?我看到AWS文档中的进程和线程有限制
Number of processes and threads (combined total) 1,024
这是否确定我的执行程序服务中的线程数?
关闭执行程序服务对AWS lambda是否像其他进程一样重要?
executorservice amazon-web-services executors threadpoolexecutor aws-lambda
executorservice ×10
java ×9
threadpool ×2
aws-lambda ×1
callable ×1
concurrency ×1
executors ×1
future ×1
javabeans ×1
predestroy ×1
queue ×1
spring ×1