标签: threadpoolexecutor

处理Java ExecutorService任务中的异常

我正在尝试使用Java的ThreadPoolExecutor类来运行具有固定数量线程的大量重量级任务.每个任务都有许多地方,在这些地方可能因异常而失败.

我已经进行了子类化,ThreadPoolExecutor并且我已经覆盖了该afterExecute方法,该方法应该在运行任务时提供任何未捕获的异常.但是,我似乎无法使其发挥作用.

例如:

public class ThreadPoolErrors extends ThreadPoolExecutor {
    public ThreadPoolErrors() {
        super(  1, // core threads
                1, // max threads
                1, // timeout
                TimeUnit.MINUTES, // timeout units
                new LinkedBlockingQueue<Runnable>() // work queue
        );
    }

    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if(t != null) {
            System.out.println("Got an error: " + t);
        } else {
            System.out.println("Everything's fine--situation normal!");
        }
    }

    public static void main( String [] args) {
        ThreadPoolErrors threadPool = new …
Run Code Online (Sandbox Code Playgroud)

java multithreading exception executorservice threadpoolexecutor

201
推荐指数
6
解决办法
15万
查看次数

146
推荐指数
7
解决办法
10万
查看次数

无法制作具有大小限制的缓存线程池?

似乎不可能创建一个缓存的线程池,它可以创建的线程数限制.

以下是在标准Java库中实现静态Executors.newCachedThreadPool的方法:

 public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
Run Code Online (Sandbox Code Playgroud)

因此,使用该模板继续创建固定大小的缓存线程池:

new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new SynchronusQueue<Runable>());
Run Code Online (Sandbox Code Playgroud)

现在,如果你使用它并提交3个任务,一切都会好的.提交任何进一步的任务将导致被拒绝的执行异常.

试试这个:

new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runable>());
Run Code Online (Sandbox Code Playgroud)

将导致所有线程按顺序执行.即,线程池永远不会有多个线程来处理您的任务.

这是ThreadPoolExecutor的execute方法中的错误?或者这可能是故意的?还是有其他方式?

编辑:我想要一些与缓存线程池完全相同的东西(它根据需要创建线程,然后在一些超时后杀死它们)但是它可以创建的线程数量受到限制,并且一旦有了它就能够继续排队其他任务达到了它的线程限制.根据sjlee的回应,这是不可能的.查看ThreadPoolExecutor的execute()方法确实是不可能的.我需要继承ThreadPoolExecutor并覆盖execute(),就像SwingWorker一样,但SwingWorker在其execute()中所做的是一个完整的hack.

java concurrency multithreading executorservice threadpoolexecutor

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

如何让ThreadPoolExecutor在排队之前将线程增加到最大值?

我已经沮丧了一段时间,其默认行为ThreadPoolExecutor支持ExecutorService我们这么多人使用的线程池.引用Javadocs:

如果有多个corePoolSize但运行的maximumPoolSize线程少于maximumPoolSize,则只有在队列已满时才会创建新线程.

这意味着如果您使用以下代码定义线程池,它将永远不会启动第二个线程,因为它LinkedBlockingQueue是无限制的.

ExecutorService threadPool =
   new ThreadPoolExecutor(1 /*core*/, 50 /*max*/, 60 /*timeout*/,
      TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(/* unlimited queue */));
Run Code Online (Sandbox Code Playgroud)

只有当您有一个有界队列并且队列已满时才会启动核心编号之上的任何线程.我怀疑大量的初级Java多线程程序员并不知道这种行为ThreadPoolExecutor.

现在我有一个特定的用例,这不是最佳的.我正在寻找方法,而不是编写我自己的TPE课程来解决它.

我的要求是针对可能不可靠的第三方回拨的Web服务.

  • 我不想与web-request同步回调,所以我想使用一个线程池.
  • 我通常会得到一些这样的一分钟,所以我不希望有newFixedThreadPool(...)大量的线程,大多数都处于休眠状态.
  • 我经常会遇到这种流量的爆发,我想将线程数量扩大到某个最大值(比方说50).
  • 我需要尽最大努力做所有回调,所以我想排队50以上的任何额外的回调.我不想通过使用a来压倒我的网络服务器的其余部分newCachedThreadPool().

更多线程启动之前,如何解决ThreadPoolExecutor队列需要限制和填充的限制?如何让它排队任务之前启动更多线程?

编辑:

@Flavio提出了使用ThreadPoolExecutor.allowCoreThreadTimeOut(true)核心线程超时并退出的好处.我考虑过这一点,但我仍然想要核心线程功能.如果可能的话,我不希望池中的线程数降到核心大小以下.

java multithreading blockingqueue threadpoolexecutor

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

核心池大小与ThreadPoolExecutor中的最大池大小

当我们谈论ThreadPoolExecutor时,核心池大小和最大池大小之间究竟有什么区别?可以借助一个例子来解释吗?

threadpoolexecutor

74
推荐指数
6
解决办法
7万
查看次数

如何在不关闭Executor的情况下等待ThreadPoolExecutor中的所有任务完成?

我无法使用shutdown(),awaitTermination()因为有可能在等待时将新任务添加到ThreadPoolExecutor中.

所以我正在寻找一种方法,等待ThreadPoolExecutor清空它的队列并完成所有任务而不停止在该点之前添加新任务.

如果它有任何区别,这适用于Android.

谢谢

更新:几周后重新访问后,我发现在这种情况下修改后的CountDownLatch对我来说效果更好.我会保留答案标记,因为它更适用于我的要求.

java multithreading android wait threadpoolexecutor

60
推荐指数
3
解决办法
6万
查看次数

使用LinkedBlockingQueue的ExecutorService与ThreadPoolExecutor

我正在开发一个多线程项目,我需要生成多个线程来测量我的客户端代码的端到端性能,因为我正在进行负载和性能测试.所以我创建了以下使用的代码ExecutorService.

以下是代码ExecutorService:

public class MultithreadingExample {

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(20);
        for (int i = 0; i < 100; i++) {
            executor.submit(new NewTask());
        }

        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    }
}

class NewTask implements Runnable {

    @Override
    public void run() {
        //Measure the end to end latency of my client code
    }   
}
Run Code Online (Sandbox Code Playgroud)

问题陈述:

现在我正在阅读互联网上的一些文章.我发现也有ThreadPoolExecutor.所以我很困惑我应该使用哪一个.

如果我将以上代码替换为:

ExecutorService executor = Executors.newFixedThreadPool(20);
    for (int i = 0; i < 100; i++) …
Run Code Online (Sandbox Code Playgroud)

java multithreading executorservice blockingqueue threadpoolexecutor

48
推荐指数
3
解决办法
4万
查看次数

Java-5 ThreadPoolExecutor相对于Java-7 ForkJoinPool有什么优势?

Java 5引入了Executor框架形式的线程池对异步任务执行的支持,其核心是java.util.concurrent.ThreadPoolExecutor实现的线程池.Java 7以java.util.concurrent.ForkJoinPool的形式添加了一个备用线程池.

查看各自的API,ForkJoinPool在标准场景中提供了ThreadPoolExecutor功能的超集(虽然严格来说ThreadPoolExecutor提供了比ForkJoinPool更多的调优机会).除此之外,fork/join任务看起来更快(可能是因为工作窃取调度程序)的观察结果显然需要更少的线程(由于非阻塞连接操作),可能会让人觉得ThreadPoolExecutor已被取代ForkJoinPool.

但这真的是对的吗?我读过的所有材料似乎总结为两种类型的线程池之间相当模糊的区别:

  • ForkJoinPool适用于许多依赖的,任务生成的,简短的,几乎不会阻塞(即计算密集型)的任务
  • ThreadPoolExecutor用于少量,独立,外部生成,长期,有时阻塞的任务

这种区别是否正确?我们能说出更具体的内容吗?

java parallel-processing threadpool threadpoolexecutor forkjoinpool

34
推荐指数
2
解决办法
5417
查看次数

ThreadPoolExecutor具有无限制队列而不创建新线程

ThreadPoolExecutor无法创建新线程.事实上,我写了一个有点hacky LinkedBlockingQueue,它将接受任何任务(即它是无限制的)但是调用一个额外的处理程序 - 在我的应用程序中喷出警告跟踪池后面 - 这给了我非常明确的信息,TPE拒绝创建新线程,即使队列中有数千个条目.我的构造函数如下:

private final ExecutorService s3UploadPool = 
new ThreadPoolExecutor(1, 40, 1, TimeUnit.HOURS, unboundedLoggingQueue);
Run Code Online (Sandbox Code Playgroud)

为什么不创建新线程?

java multithreading threadpool threadpoolexecutor

18
推荐指数
3
解决办法
9717
查看次数

外部共享资源(智能卡)的Java并发模式

我有一个Web服务器服务,客户端请求智能卡计算并获得结果.可用的智能卡号可以在服务器正常运行时间内减少或增加,例如我可以从阅读器中物理添加或删除智能卡(或许多其他事件......例如异常等).

在此输入图像描述

智能卡计算可能需要一段时间,因此如果存在对Web服务器的并发请求,我必须优化这些作业以使用所有可用的智能卡.

我想过使用智能卡线程池.至少对我而言,不寻常的是,池应该改变其大小,而不是取决于客户端请求,而只取决于智能卡的可用性.

在此输入图像描述

我研究过很多例子:

  • BlockingQueue:存储请求和停止线程等待某事做的好看.
  • FutureTask:我可以使用这个类让客户端等待它的答案,但是哪种类型的执行器应该完成任务?
  • ThreadPoolExecutor:看起来我需要什么,但有了这个我不能改变池大小,而且每个线程都应该链接到一个智能卡插槽.如果我可以更改池大小(在插入智能卡时添加线程并在移除智能卡时删除线程)以及我是否可以为每个线程分配特定智能卡,这可以是一种解决方案.

这是智能卡控件,每个智能卡有一个SmartcardWrapper,每个智能卡都有自己的插槽号.

public class SmartcardWrapper{

    private int slot;

    public SmartcardWrapper(int slot) {
        this.slot=slot;
    }   

    public byte[] compute(byte[] input) {
        byte[] out=new byte[];
        SmartcardApi.computerInput(slot,input,out); //Native method
        return out;
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用每个智能卡一个线程创建一个线程池:

private class SmartcardThread extends Thread{

    protected SmartcardWrapper sw;

    public SmartcardThread(SmartcardWrapper sw){
        this.sw=sw;
    }

    @Override
    public void run() {
        while(true){
            byte[] input=queue.take();
            byte output=sw.compute(input);
            // I have to return back the output to the client
        }           
    }
} …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading smartcard threadpoolexecutor

18
推荐指数
3
解决办法
1291
查看次数