我刚开始使用Java线程池。现在我有了一个单元测试用例,当一个新任务出现时,当前的线程号是最大值,队列已经满了。我知道在这种情况下RejectedExecutionException会被抛出。但是,如何最好地产生这样的场景,我现在能想到的是:
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,而不是一直提交任务,直到线程和队列已满。
发布于 2017-01-03 02:34:30
这是基本的想法,如果是正确的话,我需要使用EasyMock来转换它。我想知道是否有更好的方法,如果使用EasyMock,而不是一直提交任务,直到线程和队列已满。
EasyMock所做的任何事情都很可能需要比匿名Runnable更多的代码。您当然可以这样做,但是您将使用IAnswer对象而不是Runnable,所以我不确定它是否更好。
真正的问题是你在测试什么?你是真的要确保ThreadPoolExecutor在做它的工作,还是你真的想模仿一个ExecutorService,或者像@Warren提到的ThreadPoolExecutor那样。
我会在您的Thread.sleep(1000)中执行一个Runnable,并提交其中的4个,而不是while循环。您还可以在开始时创建一个对象并多次提交它。请原谅Java 7代码:
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");
}发布于 2017-01-02 02:27:58
我对EasyMock并不特别熟悉,但是一般的方法应该是模拟ThreadPoolExecutor。
发布于 2017-01-02 10:08:02
您可以将执行代码移到一个新的类中,在该类中您可以轻松地模拟出依赖项:
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);
}
}
}您的代码将更改为:
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创建一个测试,以获取ExecutorService和PrintStream的模拟,从而验证与它们的交互。
https://stackoverflow.com/questions/41420617
复制相似问题