首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java线程池抛出RejectedExecutionException的单元测试

Java线程池抛出RejectedExecutionException的单元测试
EN

Stack Overflow用户
提问于 2017-01-02 01:52:15
回答 4查看 1.3K关注 0票数 2

我刚开始使用Java线程池。现在我有了一个单元测试用例,当一个新任务出现时,当前的线程号是最大值,队列已经满了。我知道在这种情况下RejectedExecutionException会被抛出。但是,如何最好地产生这样的场景,我现在能想到的是:

代码语言:javascript
运行
复制
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(1);
ExecutorService ex = new ThreadPoolExecutor(2, 2, 60L, TimeUnit.MILLISECONDS, queue);
int rejected = 0;
try{
    while (true){
        ex.submit(() -> {
            System.out.println("Queue remaining size: " + queue.remainingCapacity());
            System.out.println("Thread amount in pool: " + ((ThreadPoolExecutor)ex).getPoolSize() + "\n");
        });
    }
}
catch (RejectedExecutionException e){
    System.out.println(++rejected);
}

这是基本的想法,如果是正确的话,我需要使用EasyMock来转换它。我想知道是否有更好的方法,如果使用EasyMock,而不是一直提交任务,直到线程和队列已满。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-03 02:34:30

这是基本的想法,如果是正确的话,我需要使用EasyMock来转换它。我想知道是否有更好的方法,如果使用EasyMock,而不是一直提交任务,直到线程和队列已满。

EasyMock所做的任何事情都很可能需要比匿名Runnable更多的代码。您当然可以这样做,但是您将使用IAnswer对象而不是Runnable,所以我不确定它是否更好。

真正的问题是你在测试什么?你是真的要确保ThreadPoolExecutor在做它的工作,还是你真的想模仿一个ExecutorService,或者像@Warren提到的ThreadPoolExecutor那样。

我会在您的Thread.sleep(1000)中执行一个Runnable,并提交其中的4个,而不是while循环。您还可以在开始时创建一个对象并多次提交它。请原谅Java 7代码:

代码语言:javascript
运行
复制
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(1);
ExecutorService ex = new ThreadPoolExecutor(2, 2, 60L, TimeUnit.MILLISECONDS, queue);
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
    }
};
try {
    ex.submit(runnable); // 1st thread
    ex.submit(runnable); // 2nd thread
    ex.submit(runnable); // 1st queued
    ex.submit(runnable); // rejected
} catch (RejectedExecutionException e) {
    System.out.println("rejected");
}
票数 1
EN

Stack Overflow用户

发布于 2017-01-02 02:27:58

我对EasyMock并不特别熟悉,但是一般的方法应该是模拟ThreadPoolExecutor。

票数 1
EN

Stack Overflow用户

发布于 2017-01-02 10:08:02

您可以将执行代码移到一个新的类中,在该类中您可以轻松地模拟出依赖项:

代码语言:javascript
运行
复制
class MyExecuter extends Executer{
  private final ExecuterService executerService;
  private final PrintStream out;
  MyExecuter(ExecutorService executerService, PrintStream out){
    this.executerService  =  executerService;
    this.out  =  out;
  }
  @override 
   public void execute(Runnable r) {
     int rejected = 0;
     try{
        while (true)
        {
            executerService.submit(() -> {
               // do your business logic which usually does not care about the executor or the queue...
            });
        }
    }
    catch (RejectedExecutionException e)
    {
        out.println(++rejected);
    }

   }
}

您的代码将更改为:

代码语言:javascript
运行
复制
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(1);
ExecutorService ex = new ThreadPoolExecutor(2, 2, 60L, TimeUnit.MILLISECONDS, queue);
Executor mex = new MyExcecutor(ex, System.out);
mex.execute();

现在,您可以为MyExcecutor创建一个测试,以获取ExecutorServicePrintStream的模拟,从而验证与它们的交互。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41420617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档