• Post Reply Bookmark Topic Watch Topic
  • New Topic

Uniqueness in Future Task: Same task when submitted twice executes only once  RSS feed

 
Stanley Walker
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have been playing around FutureTask recently. I wanted to fetch data from two tables in a parallel execution. Currently my solution is mocked, where it just fetches some hardcoded data.

1. I created futuretask1 which fetches data from 1st table
2. I created futuretask2 which fetches data from 2nd table
3. I submitted the task to executor services for execution. Things are working fine.
4. However my problem is if I submit any one of the future task twice, i do not see execution happening twice. Clearly java is not executing a task which it has already executed. However I could not find anything alluding to it in the java docs for ExecutorService or Executor. I had also opened up the java api, and I could not figure out how it detects uniqueness.

Clearly I am missing out something here, any help would be appreciated.
My code snippets are given below:



The classes DataFromFirstTable and DataFromSecondTable are simple POJO's







The output that i get on running the above code is:



MockedFetchFromTable.loadDataFromFirstTable()
MockedFetchFromTable.loadDataFromSecondTable()
MockedFetchFromTable.parallelFetchFromTwoTable() second result----->nameId#first name#secondName
MockedFetchFromTable.parallelFetchFromTwoTable() result----->AUD#10



The output tells me that even though I have submitted my futuretask2 twice, the line MockedFetchFromTable.loadDataFromSecondTable() is only getting printed once.

Please help.

Also one more question, if i do not shutdown my executorservice manually , i can see that my program waits for close to a minute even after all execution is complete. Is this normal behavior? or have i done something wrong?

 
chandan Khatri
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stanley Walker wrote:

The output tells me that even though I have submitted my futuretask2 twice, the line MockedFetchFromTable.loadDataFromSecondTable() is only getting printed once.

Please help.

Also one more question, if i do not shutdown my executorservice manually , i can see that my program waits for close to a minute even after all execution is complete. Is this normal behavior? or have i done something wrong?



As to answer your first question, you are submitting a same task multiple times and that task cannot be started again as its already been assigned to the pool. (Please correct me if I am wrong.)
And your second question baffled me as well, no idea why it waits for one minute or so before program waits. Let's wait for some experts comment on this.



 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stanley Walker wrote:4. However my problem is if I submit any one of the future task twice, i do not see execution happening twice. Clearly java is not executing a task which it has already executed. However I could not find anything alluding to it in the java docs for ExecutorService or Executor. I had also opened up the java api, and I could not figure out how it detects uniqueness.

Clearly I am missing out something here, any help would be appreciated.

FutureTasks are used for tasks that are designed to run once. They have an internal state that goes from Ready to Running to Ran (or Cancelled). The task will only be executed if the task is in the Ready state, because running it while in the Running or Ran state could destroy the internal data result from the first run. There is an alternate run method called runAndReset() but there isn't a good way to get your executor to use it (and besides, it works by not storing the results of the run.). We know this because the API for FutureTask says "Once the computation has completed, the computation cannot be restarted or cancelled (unless the computation is invoked using runAndReset())." If you want a task that can run multiple times, then you are best off using Callable. When you submit a task you will be given a Future which you can use to track the outcome, cancel, and get results from.

Also one more question, if i do not shutdown my executorservice manually , i can see that my program waits for close to a minute even after all execution is complete. Is this normal behavior? or have i done something wrong?

Are you running in an IDE or unit test framework? I would expect the executors to keep running forever. the Executors hold a queue of non-daemon threads, which means they will continue to run even all your threads are done, this is expected behavior. You could create an explicit ThreadPoolExecutor (instead of using Executors.newChachedThreadPool()) and provide a ThreadFactory which generates Daemon threads, but then you risk the tasks you submitting not being executed if your calling code does not last as long as the executing code. Of you can do the explicit shutdown which tells the Executor to stop accepting tasks and kill all threads when the currently queued tasks are complete. Most often this second approach is the correct one.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
chandan Khatri wrote:As to answer your first question, you are submitting a same task multiple times and that task cannot be started again as its already been assigned to the pool. (Please correct me if I am wrong.)

This isn't quite right. It actually has nothing to do with the pool. If you ran futureTask.run() twice, without using an Executor or other redirection, it would still only execute the callable's code once. It is internal state of the FutureTask which causes the problem.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!