use*_*351 6 java concurrency multithreading
我正在寻找一种方法来限制线程的数量,这些线程可以使用信号量或类似的方式在Java中运行某些代码段.
我们正在研究类似于Google Guava RateLimiter的东西- 但不是每秒限制数量调用,我们需要限制运行关键代码段的线程数.
需要这个的原因是我们使用的某些库在这里有问题所以我们只是寻找一个快速的解决方法.
不过,Semaphore
如果您小心的话,这是最好的选择(请参阅@Bex的答案),也可以使用ExecutorService
。只需将您想保护的代码片段包装到一个Callable
任务中,以防止无限的并发访问,然后将这些任务提交给executor服务:
// 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());
Run Code Online (Sandbox Code Playgroud)
使用,ExecutorService
您还可以使用Runnable
代替Callable
,invokeAll()
而不是execute
,等待任务完成,取消任务,从任务中返回值并执行其他一些有用的操作。
Java 8使它更简单,您可以使用lambda代替定义任务类:
executor.submit(() -> {
// Do the work here
});
Run Code Online (Sandbox Code Playgroud)
这正是java.util.concurrent.Semaphore
设计目的.你这样创建Semaphore
:
final int MAX_NOF_THREADS = 5;
final Semaphore mySemaphore = new Semaphore(MAX_NOF_THREADS);
Run Code Online (Sandbox Code Playgroud)
那么你要做的关键领域:
try {
mySemaphore.aquire(); // This will hang until there is a vacancy
do_my_critical_stuff();
} finally {
mySemaphore.release();
}
Run Code Online (Sandbox Code Playgroud)
... 就如此容易.