Java 如何限制作用于方法的线程数
Java how to limit number of threads acting on method
我的 Web 应用程序中有 java 方法执行繁重的文件操作。问题是,如果超过 5 个线程同时出现(将在测试阶段出现),它就会崩溃。我的意思是它无法处理繁忙的交通。
这就是为什么我想一次处理最多 5 个请求的方法,如果第 6 个请求到来,它将等到前 5 个请求之一完成
public synchronized void add(int value){
File a=new File("D:/heavyFile1");
File b=new File("D:/heavyFile2");
File c=new File("D:/heavyFile3");
//operation on file
}
我添加了 synchronized 关键字,但它一次只能处理一个请求,导致性能问题,因为每个下一个线程都必须等到它完成。请帮助我。
您可以创建一个 Executor
,并使用 Semaphore
限制它接受的任务数量。像这样:
private final Semaphore semaphore = new Semaphore(4);
ThreadPoolExecutor tp= new ThreadPoolExecutor(...){
public void execute(Runnable r){
semaphore.acquire();
super.execute(r);
}
public void afterExecute(Runnable r, Thread t){
semaphore.release();
super.afterExecute(r,t);
}
};
您可以使用限制为 5 个线程的 ThreadPool
。在此,您创建一个 ThreadPool 并向其提交一个新线程以处理您的 class。它只会允许您配置的最大线程数同时工作。如果线程数量超过配置数量,它们将不得不等待某个工作线程完成它的任务。
创建一个具有固定大小的 thread pool 来执行此操作。
信号量。在里面。有 5 个单元,让线程在函数顶部等待,并在结束时发出信号。
您可以在执行逻辑内部使用 Executor.newFixedThreadPool
习惯用法。
完整示例如下:
public class Main {
public static void main(String[] args) throws Exception {
Main m = new Main();
// simulating a window of time where your method is invoked continuously
for (int i = 0; i < 11; i++) {
m.doSomething();
}
// shutting down executor when done
m.terminate();
}
ExecutorService executor = Executors.newFixedThreadPool(5);
// internally submits a new task to the executor
public void doSomething() {
executor.submit(new Runnable() {
@Override
public void run() {
long wait = ThreadLocalRandom.current().nextLong(2000);
try {
System.out.printf(
"%s is sleeping for %dms.%n",
Thread.currentThread().getName(),
wait
);
Thread.sleep(wait);
}
catch (InterruptedException ie) {
// suppressed
}
System.out.printf(
"%s is doing something!%n",
Thread.currentThread().getName()
);
}
});
}
public void terminate() throws Exception {
executor.shutdown();
}
}
输出
会有所不同,大致如下:
pool-1-thread-1 is sleeping for 1533ms.
pool-1-thread-4 is sleeping for 784ms.
pool-1-thread-3 is sleeping for 684ms.
pool-1-thread-5 is sleeping for 1375ms.
pool-1-thread-2 is sleeping for 1717ms.
pool-1-thread-3 is doing something!
pool-1-thread-3 is sleeping for 1252ms.
pool-1-thread-4 is doing something!
pool-1-thread-4 is sleeping for 301ms.
pool-1-thread-4 is doing something!
pool-1-thread-4 is sleeping for 1140ms.
pool-1-thread-5 is doing something!
pool-1-thread-5 is sleeping for 1454ms.
pool-1-thread-1 is doing something!
pool-1-thread-1 is sleeping for 1594ms.
pool-1-thread-2 is doing something!
pool-1-thread-2 is sleeping for 227ms.
pool-1-thread-3 is doing something!
pool-1-thread-2 is doing something!
pool-1-thread-4 is doing something!
pool-1-thread-5 is doing something!
pool-1-thread-1 is doing something!
备注
查看重复使用的线程名称,这些是新提交的任务,在池中分配了一个空闲线程。
我的 Web 应用程序中有 java 方法执行繁重的文件操作。问题是,如果超过 5 个线程同时出现(将在测试阶段出现),它就会崩溃。我的意思是它无法处理繁忙的交通。
这就是为什么我想一次处理最多 5 个请求的方法,如果第 6 个请求到来,它将等到前 5 个请求之一完成
public synchronized void add(int value){
File a=new File("D:/heavyFile1");
File b=new File("D:/heavyFile2");
File c=new File("D:/heavyFile3");
//operation on file
}
我添加了 synchronized 关键字,但它一次只能处理一个请求,导致性能问题,因为每个下一个线程都必须等到它完成。请帮助我。
您可以创建一个 Executor
,并使用 Semaphore
限制它接受的任务数量。像这样:
private final Semaphore semaphore = new Semaphore(4);
ThreadPoolExecutor tp= new ThreadPoolExecutor(...){
public void execute(Runnable r){
semaphore.acquire();
super.execute(r);
}
public void afterExecute(Runnable r, Thread t){
semaphore.release();
super.afterExecute(r,t);
}
};
您可以使用限制为 5 个线程的 ThreadPool
。在此,您创建一个 ThreadPool 并向其提交一个新线程以处理您的 class。它只会允许您配置的最大线程数同时工作。如果线程数量超过配置数量,它们将不得不等待某个工作线程完成它的任务。
创建一个具有固定大小的 thread pool 来执行此操作。
信号量。在里面。有 5 个单元,让线程在函数顶部等待,并在结束时发出信号。
您可以在执行逻辑内部使用 Executor.newFixedThreadPool
习惯用法。
完整示例如下:
public class Main {
public static void main(String[] args) throws Exception {
Main m = new Main();
// simulating a window of time where your method is invoked continuously
for (int i = 0; i < 11; i++) {
m.doSomething();
}
// shutting down executor when done
m.terminate();
}
ExecutorService executor = Executors.newFixedThreadPool(5);
// internally submits a new task to the executor
public void doSomething() {
executor.submit(new Runnable() {
@Override
public void run() {
long wait = ThreadLocalRandom.current().nextLong(2000);
try {
System.out.printf(
"%s is sleeping for %dms.%n",
Thread.currentThread().getName(),
wait
);
Thread.sleep(wait);
}
catch (InterruptedException ie) {
// suppressed
}
System.out.printf(
"%s is doing something!%n",
Thread.currentThread().getName()
);
}
});
}
public void terminate() throws Exception {
executor.shutdown();
}
}
输出
会有所不同,大致如下:
pool-1-thread-1 is sleeping for 1533ms.
pool-1-thread-4 is sleeping for 784ms.
pool-1-thread-3 is sleeping for 684ms.
pool-1-thread-5 is sleeping for 1375ms.
pool-1-thread-2 is sleeping for 1717ms.
pool-1-thread-3 is doing something!
pool-1-thread-3 is sleeping for 1252ms.
pool-1-thread-4 is doing something!
pool-1-thread-4 is sleeping for 301ms.
pool-1-thread-4 is doing something!
pool-1-thread-4 is sleeping for 1140ms.
pool-1-thread-5 is doing something!
pool-1-thread-5 is sleeping for 1454ms.
pool-1-thread-1 is doing something!
pool-1-thread-1 is sleeping for 1594ms.
pool-1-thread-2 is doing something!
pool-1-thread-2 is sleeping for 227ms.
pool-1-thread-3 is doing something!
pool-1-thread-2 is doing something!
pool-1-thread-4 is doing something!
pool-1-thread-5 is doing something!
pool-1-thread-1 is doing something!
备注
查看重复使用的线程名称,这些是新提交的任务,在池中分配了一个空闲线程。