Reputation:
I am working on a project in which I will be spawning multiple threads from a multithreaded code.
Suppose I am spawning 10 threads, then I need to make sure each thread should be running for particular duration of time.
For example, if I want each thread
should run for 30 minutes
, then in the config.properties
file, I will be having TOTAL_RUNNING_TIME=30
So I came up with the below design to make sure each thread is running for 30 minutes
.
private static long durationOfRun;
private static long sleepTime;
public static void main(String[] args) {
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(threads);
try {
readPropertyFile();
for (int i = 0; i < threads; i++) {
service.submit(new ReadTask(durationOfRun, sleepTime));
}
}
}
private static void readPropertyFile() throws IOException {
prop.load(Read.class.getClassLoader().getResourceAsStream("config.properties"));
threads = Integer.parseInt(prop.getProperty("NUMBER_OF_THREADS"));
durationOfRun = Long.parseLong(prop.getProperty("TOTAL_RUNNING_TIME"));
sleepTime = Long.parseLong(prop.getProperty("SLEEP_TIME"));
}
Below is my ReadTask class.
class ReadTask implements Runnable {
private long durationOfRun;
private long sleepTime;
public ReadTask(long durationOfRun, long sleepTime) {
this.durationOfRun = durationOfRun;
this.sleepTime = sleepTime;
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun*60*1000);
//Each thread is running less than endTime
while(System.currentTimeMillis() <= endTime) {
//Do whatever you want to do
}
Thread.sleep(sleepTime);
}
}
If you take a look into my run method, I have a while loop which will check the time. So this approach of making each thread run for particular duration of time is correct or not? Or is there any better way also? Please ignore my ignorance if there are any other better approach or this will also serve the purpose?
Let me know if there are any thread safety issues here as well?
What I am looking for is each thread should run for 30 minutes and if the time for that thread has finished, then complete the task on which it is running currently and do not take anything else after that, just like we have shutdown
for ExecutorService
. If there is any better approach or better design than this. Please provide me some example so that I can learn that stuff just from my knowledge point of view. Thanks for the help.
UPDATE:-
If you take a look into my while loop in the run method, inside that while loop I will be trying to make a Select call to the database
. So what I am looking is something like this- As soon as the time for that thread is finished, it will not make any other select call to the database and finished whatever it was doing previously. Just like shutdown
works for ExecutorService
.
And I don't want this scenario- as soon as the time for that thread is finished, it will timeout the thread as it might be possible, that particular thread was doing select to database in that period?
Upvotes: 2
Views: 3812
Reputation: 347194
One of the concerns I have with this design, is what if the amount of work being done within the while-loop takes more to them the time our?
For example
while(System.currentTimeMillis() <= endTime) {
calaculateTheMeaningOfLife();
}
What happens now? What's stopping the thread, or encouraging it to check the timeout? The samething will occur if you have a blocking operation, such as a File or socket read/write
You could try to interrupt the thread, but there is no guareentee that this will help
Upvotes: 1
Reputation: 1246
You can set the time limit to the the executor. You need to cast the executor returned by Executors and set the time limit:
ThreadPoolExecutor service = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);
service.setKeepAliveTime(1800, TimeUnit.SECONDS);
Taken from "Java Concurrency in Practice" by Brian Goetz.
Upvotes: 0