标签: executorservice

在webapp中正常关闭ExecutorService?

在我的webapp中,我创建了一个ExecutorService使用固定大小的ThreadPool的服务.我ExecutorService在整个应用程序生命周期中重复使用它.

private static ExecutorService pool = Executors.newFixedThreadPool(8);
Run Code Online (Sandbox Code Playgroud)

所有都在Tomcat中运行,它在向下发出错误时给出了以下错误:

appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Run Code Online (Sandbox Code Playgroud)

我确实意识到我需要在关闭tomcat之前关闭ExecutorService.Soms SO线程已经谈到了这一点,但我找不到一个干净的方法来处理这个问题.

我是否应该ShutdownHook线程和执行程序的正常关闭中使用@ Tim-bender ?或者我应该使用CachedThreadPool吗?

java multithreading executorservice tomcat6

23
推荐指数
2
解决办法
7095
查看次数

如何使用invokeAll()让所有线程池完成他们的任务?

    ExecutorService pool=Executors.newFixedThreadPool(7);
        List<Future<Hotel>> future=new ArrayList<Future<Hotel>>();
        List<Callable<Hotel>> callList = new ArrayList<Callable<Hotel>>();

        for(int i=0;i<=diff;i++){

            String str="2013-"+(liDates.get(i).get(Calendar.MONTH)+1)+"-"+liDates.get(i).get(Calendar.DATE);

            callList.add(new HotelCheapestFare(str));

        }       
     future=pool.invokeAll(callList);
for(int i=0;i<=future.size();i++){

        System.out.println("name is:"+future.get(i).get().getName());
    }
Run Code Online (Sandbox Code Playgroud)

现在我想invokeAll在进入for循环之前将pool放到所有任务中,但是当我运行这个程序for循环时,在此之前执行invokeAll并抛出此异常:

java.util.concurrent.ExecutionException: java.lang.NullPointerException at 
java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source) at  
java.util.concurrent.FutureTask.get(Unknown Source) at 
com.mmt.freedom.cheapestfare.TestHotel.main(TestHotel.java:6??5)

Caused by: java.lang.NullPointerException at 
com.mmt.freedom.cheapestfare.HotelCheapestFare.getHotelCheap?estFare(HotelCheapes??tFare.java:166) 
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe??apestFare.java:219)
at com.mmt.freedom.cheapestfare.HotelCheapestFare.call(HotelChe??apestFare.java:1) 
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) atjava.util.concurrent.ThreadPoolExecutor$Worker.run(Unknow??n Source)
at java.lang.Thread.run
Run Code Online (Sandbox Code Playgroud)

java multithreading future arraylist executorservice

22
推荐指数
2
解决办法
5万
查看次数

ExecutorService与Casual Thread Spawner

我有一个关于如何ExecutorService在Java中工作的基本问题.

很难看出简单地创建Threads并行执行某些任务和将每个任务分配给它们之间的区别ThreadPool.

使用起来ExecutorService也非常简单和有效,所以我想知道为什么我们不一直使用它.

这只是一种比另一种方式更快地执行其工作的问题吗?

这里有两个非常简单的例子来说明两种方式之间的区别:

使用执行程序服务:Hello World(任务)

static class HelloTask implements Runnable {
    String msg;

    public HelloTask(String msg) {
        this.msg = msg; 
    }
    public void run() {
        long id = Thread.currentThread().getId();
        System.out.println(msg + " from thread:" + id);
    }
}
Run Code Online (Sandbox Code Playgroud)

使用执行程序服务:Hello World(创建执行程序,提交)

static class HelloTask {
    public static void main(String[] args) {
        int ntasks = 1000;
        ExecutorService exs = Executors.newFixedThreadPool(4);

        for (int i=0; i<ntasks; i++) { 
            HelloTask t = new HelloTask("Hello from …
Run Code Online (Sandbox Code Playgroud)

java multithreading executorservice

22
推荐指数
2
解决办法
1万
查看次数

如何在FutureTask中捕获异常

在发现在Java 1.6上FutureTask运行Executors.newCachedThreadPool()(以及从Eclipse中)吞下Runnable.run()方法中的异常后,我试图找到一种方法来捕获这些,而不向我的所有Runnable实现添加throw/catch .

API建议覆盖FutureTask.setException()应该有助于此:

导致此未来报告ExecutionException,并将给定的throwable作为其原因,除非已设置或已取消此Future.在计算失败时,run方法在内部调用此方法.

但是,似乎没有调用此方法(使用调试器运行显示异常被捕获FutureTasksetException未被调用).我写了以下程序来重现我的问题:

public class RunTest {
    public static void main(String[] args) {
        MyFutureTask t = new MyFutureTask(new Runnable() {

            @Override
            public void run() {
                throw new RuntimeException("Unchecked exception");

            }
        });

        ExecutorService service = Executors.newCachedThreadPool();
        service.submit(t);
    }
}

public class MyFutureTask extends FutureTask<Object> {

    public MyFutureTask(Runnable r) {
        super(r, null);
    }

    @Override
    protected void setException(Throwable t) {
        super.setException(t);
        System.out.println("Exception: " + t);
    } …
Run Code Online (Sandbox Code Playgroud)

java concurrency executorservice futuretask

21
推荐指数
3
解决办法
2万
查看次数

在ScheduledExecutorService中运行的任务本身内停止定期任务

在ScheduledExecutorService中运行时,是否有一种很好的方法可以阻止任务内部重复任务?

可以说,我有以下任务:

Future<?> f = scheduledExecutor.scheduleAtFixedRate(new Runnable() {
    int count = 0;
    public void run() {
       System.out.println(count++);
       if (count == 10) {
           // ??? cancel self
       }
    }
}, 1, 1, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)

从外面看,很容易通过f.cancel()取消,但是如何在指定的地方停止重复?(通过AtomicReference传递Future是不安全的,因为当scheduleAtFixedRate返回f迟到且变量设置得太晚时,有一个潜在的窗口,并且任务本身可能已经运行,在引用中看到null.)

java concurrency anonymous-class executorservice variable-initialization

21
推荐指数
2
解决办法
1万
查看次数

如何在Java中的ExecutorService中暂停/恢复所有线程?

我向Java中的executorservice提交了大量工作,我想以某种方式暂时暂停所有这些工作.最好的方法是什么?我该如何恢复?或者我这样做完全错了?我应该遵循一些其他模式来实现我想要达到的目标(即暂停/恢复执行服务的能力)吗?

java parallel-processing concurrency multithreading executorservice

21
推荐指数
3
解决办法
2万
查看次数

遗嘱执行人是否可以重复使用?

一个执行器对象是否意味着在一个shutdown?之后重用?我的意思是,如果我调用shutdownshutdownNow在执行程序终止后,我应该new创建一个新的线程池,还是可以以某种方式"重置"/重用以前终止的执行程序并重用它?

更新:
如果我需要创建新的线程池,我怎么能"理解"前一个已停止?
例如以下内容:

public void startPool(){  
   if(threadPool != null && !threadPool.isShutdown()){
    return;
   }  
   threadPool = Executors.newCachedThreadPool();  
   //other stuff

}  

public void stopPool(){  
   if(threadPool != null){  
    threadPool.shutdown();   
  }  
}   
Run Code Online (Sandbox Code Playgroud)

不管用.如果我调用stop然后start由于条件将不会创建新的线程池.编码的正确方法是什么?

java concurrency executorservice java.util.concurrent

21
推荐指数
3
解决办法
7529
查看次数

执行者中的Thread.join()等价物

我有一个新手问题.我有这个代码:

public class Main 
{

    public static void main(String[] args) throws InterruptedException 
    {
        // TODO Auto-generated method stub
        IntHolder aHolder=new IntHolder();
        aHolder.Number=0;

        IncrementorThread A= new IncrementorThread(1, aHolder);
        IncrementorThread B= new IncrementorThread(2, aHolder);
        IncrementorThread C= new IncrementorThread(3, aHolder);

        A.start();
        B.start();
        C.start();

        A.join();
        B.join();
        C.join();
        System.out.println("All threads completed...");

    }

}
Run Code Online (Sandbox Code Playgroud)

这将等待所有线程完成.如果我这样使用Executors:

public class Main 
{

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        IntHolder aHolder=new IntHolder();
        aHolder.number=0;

        IncrementalRunable A= new IncrementalRunable(1, aHolder);
        IncrementalRunable B= new IncrementalRunable(2, aHolder); …
Run Code Online (Sandbox Code Playgroud)

java multithreading executorservice

21
推荐指数
2
解决办法
2万
查看次数

ExecutorService awaitTermination卡住了

我用一个固定大小的线程池Executors.newFixedThreadPool(2),我执行了10个Runnable对象.我设置断点并追踪执行.但是,fixedSizeThreadPool.awaitTermination()即使完成了所有任务,也不允许我继续.

基本上:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
for (int i = 0; i < 10; ++i) {
    fixedSizeThreadPool.execute(myRunables[i]);
}
try {
    fixedSizeThreadPool.awaitTermination(timeout, timeoutUnits);
} catch (Exception e) { }
System.out.println("done!");
Run Code Online (Sandbox Code Playgroud)

但这总是被困住awaitTermination.怎么了?

java multithreading executorservice java.util.concurrent

20
推荐指数
1
解决办法
9996
查看次数

在ExecutorService上安排的守护程序线程; 解释为什么这是不好的形式

我对按顺序关闭调度的线程的想法很满意ExectuorService; 也就是说,调用shutdownshutdownNow将导致池上创建的线程正常退出.如果他们回复interrupt你,你可以确定最终会被调用等等,你会得到一个干净,可预测的退出(你可以清理任何资源等).

但是,如果您已将线程设置为守护程序(通过执行程序ThreadFactory),如下所示.

ExecutorService pool = Executors.newSingleThreadExecutor(new ThreadFactory() {
   @Override
   public Thread newThread(Runnable runnable) {
      Thread thread = Executors.defaultThreadFactory().newThread(runnable);
      thread.setDaemon(true);
      return thread;
   }
});
Run Code Online (Sandbox Code Playgroud)

主线程终止后,VM将突然终止任何守护程序线程.在上面的示例中,调度然后突然终止的(守护进程)线程将绕过任何finally块,并且任何可中断的方法都不会抛出InterruptedException.

所以,我倾向于认为,这标志着一个使用线程ThreadPoolExecutor的池守护进程是不好的做法...我的问题是真的请他帮我练声曲为什么.

为什么在ExecutorService线程池中使用守护程序线程是不好的做法(或者如果你不同意)?特别是我有兴趣通过正常关闭(具有中断策略并且运行良好的线程)与守护程序线程来描述VM关闭的生命周期.

扩展最后一点,finalizeon ThreadPoolExecutor将调用shutdown自身,但是当它使用守护程序线程时,如果finalizeVM调用它们,它们可能已经终止.那么线程池的行为是什么呢?如果底层线程突然终止,它是否可以被欺骗以保持活着(因此不会退出VM)?

我问的部分原因是因为我已经看到它曾经绕过了关闭实际的ExectorService的需要.您能想到绕过关闭生命周期会产生不良影响的情况吗?到目前为止,我可以提出使用守护进程的唯一原因是采取捷径,我想欣赏它可能导致的任何意外的副作用.

java concurrency multithreading daemon executorservice

20
推荐指数
3
解决办法
2万
查看次数