我正在寻找一种限制线程数的方法,这些线程可以使用信号量或类似的方式在Java中运行某段代码。
我们正在寻找与Google Guava RateLimiter类似的东西 - 但不是每秒限制数量调用,我们需要限制运行关键代码段的线程数。
之所以需要这个,我们使用的某些库在这里存在问题,所以我们只是寻找一个快速的解决方法。
答案 0 :(得分:6)
这正是java.util.concurrent.Semaphore
的目的。您可以像这样创建Semaphore
:
final int MAX_NOF_THREADS = 5;
final Semaphore mySemaphore = new Semaphore(MAX_NOF_THREADS);
然后是你要做的关键领域:
try {
mySemaphore.aquire(); // This will hang until there is a vacancy
do_my_critical_stuff();
} finally {
mySemaphore.release();
}
......就这么简单。
答案 1 :(得分:5)
尽管如此,Semaphore
是最好的选择(看看@ Bex的答案),如果你小心,也可以使用ExecutorService
。只需将您想要保护的代码包装成无限制的并发访问Callable
任务,并将这些任务提交给执行程序服务:
// Task that will be executed
public class MyTask implements Callable<Void> {
@Override
public Void call() {
// Do the work here
return null;
}
}
// Service to execute tasks in no more than 5 parallel threads
// Cache it after creation and use when you need to execute a task
int maxThreadsCount = 5;
ExecutorService executor = Executors.newFixedThreadPool(maxThreadsCount);
// Execute a task. It will wait if all 5 threads are busy right now.
executor.submit(new MyTask());
使用ExecutorService
,您还可以使用Runnable
代替Callable
,invokeAll()
代替execute
,等待任务完成,取消任务,返回值他们并做一些其他有用的事情。
Java 8使其变得更简单,您可以使用lambdas而不是定义任务类:
executor.submit(() -> {
// Do the work here
});