Reputation: 803
I have java method in my web application doing heavy file operation. The thing is, if more than 5 threads come simultaneously (which will come in testing phase) it breaks down. I mean it cannot handle heavy traffic.
That's why I want to handle maximum 5 requests at a time for method if 6th request come it will wait until one of the first 5 finished
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
}
I have added synchronized keyword but it only handles one request at a time leading to performance issue as every next thread have to wait till it is finished. Please help me.
Upvotes: 1
Views: 3856
Reputation: 48444
You can use the Executor.newFixedThreadPool
idiom, internally to your execution logic.
Full example below:
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();
}
}
Output
Will vary, in the lines of:
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!
Note
See the re-used thread names, those are new submitted tasks that are assigned a vacant thread in the pool.
Upvotes: 3
Reputation: 24907
Semaphore. Init. with 5 units and have the threads wait at the top of the function and signal at the end.
Upvotes: 1
Reputation: 2119
You can use a ThreadPool
with a limit of 5 threads. In this, you create a ThreadPool and submit a new thread to it for work on your class. It will only allow maximum number of threads to work simultenously which you have configured. If more threads than configured number comes, they will have to wait until some worker thread finishes it's task.
An example : http://www.javacodegeeks.com/2013/01/java-thread-pool-example-using-executors-and-threadpoolexecutor.html
Upvotes: 0
Reputation: 30568
You can create an Executor
, and limit the number of tasks it accepts using a Semaphore
. Something like this:
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);
}
};
Upvotes: 2