Multi threading issue --> retrieving thread result after his completion - java

Here is my code :
List<Object> array= new ArrayList<Object>();
int i=0;
ExecutorService pool = Executors.newFixedThreadPool(50);
for(String str : strList) {
LittleDwarfWorker littleDwarfWorker = new LittleDwarfWorker(params including a datasource);
try {
pool.execute(littleDwarfWorker);
}catch(Exception e) {
e.printStackTrace();
}
finally{
i++;
array.add(littleDwarfWorker.getResult());
if((i%100)==0) {
log.info("Progression :"+i+"/"+listeEan.size());
}
}
}
pool.shutdown();
Here my beloved dwarf :
public void run() {
JdbcTemplate localJdbcTemplate = new JdbcTemplate(this.dataSource);
//dwarf dig in database to find some diamonds
}
My issue is when I run, arrayis empty. I guess my code is bad-formatted but I'm not comfortable enought with multi threading to find my error. I suppose the array.add() instruction is executed before my thread finishes his work, so value is empty.
What I'm looking for :
each thread get his own worker, when worker has result it add the result to my array.
For me finally would be executed AFTER my thread retrieve info from db.
I looked at submit method here Returning value from Thread but i'm not sure about how retrieve "future" value. Because if my run method isn't void I get an error.

The ExecutorService in java does not work this way. I guess that you LittleDwarfWorker implmenets Runnable and that the getResult() is your creation. To make is the java way you your worker needs to implements Callable<Object> which allows you to directly get the result after the task has finished. You also need a CompletionService. So you first submit all tasks and afterwards collected their result. The .take() returns a Future<V> which hold you result, so it will block until it is ready.
ExecutorService executor = Executors.newFixedThreadPool(50);
CompletionService<Obejct> completionService = new ExecutorCompletionService<> (executor);
for(String str : strList) {
completionService.submit(new LittleDwarfWorker(...));
}
for ( int i = 0; i < strList.size(); i++ ) {
try {
Object result = completionService.take().get();
// ... do whatever something with the object
} catch ( InterruptedException | ExecutionException e ) {
e.printStackTrace();
}
}
executor.shutdown();

Related

is invokeAll() a blocking call in java 7

ExecutorService executorService = Executors.newSingleThreadExecutor();
Set<Callable<String>> callables = new HashSet<Callable<String>>();
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 1";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 2";
}
});
callables.add(new Callable<String>() {
public String call() throws Exception {
return "Task 3";
}
});
List<Future<String>> futures = executorService.invokeAll(callables);
for(Future<String> future : futures){
System.out.println("future.get = " + future.get());
}
For this code piece. My question is "is invokeAll() a blocking call "?
I mean, when code ran to invokeAll() line, are we bloking there to wait for all result been generated?
Executes the given tasks, returning a list of Futures holding their
status and results when all complete. Future.isDone() is true for each
element of the returned list. Note that a completed task could have
terminated either normally or by throwing an exception. The results of
this method are undefined if the given collection is modified while
this operation is in progress.
Futures can only be done when execution is finished, therefore this method can only return when the tasks have been executed.
That it can throw an InterruptedException is also indicative of a blocking action.
Looking at the implementation of invokeAll in java.util.concurrent.AbstractExecutorService (comment inline):
// from OpenJDK source; GPL-2.0-with-classpath-exception
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) {
try {
f.get(); // <== *** BLOCKS HERE ***
} catch (CancellationException ignore) {
} catch (ExecutionException ignore) {
}
}
}
done = true;
return futures;
} finally {
if (!done)
for (int i = 0, size = futures.size(); i < size; i++)
futures.get(i).cancel(true);
}
}
In fact, looking at a reference implementation is what you generally should do in these cases when the Javadoc-Specese appears to be difficult to decipher. (with the caveat in mind that some implementation details are not part of the spec.)
You mean if the parent thread will wait for all the thread created using your ExecutorService invocation? Then answer is yes, parent thread will wait and once all threads are finished you will get the list of Futures object which will hold the result of each thread execution.
See below from ExecutorService.invokeAll()
Executes the given tasks, returning a list of Futures holding their
status and results when all complete.
InvokeAll method blocks till all the tasks are completed and list of futures are returned,
Solution:
If we don't want this to happen and continue with execution of program ,we can Loop through the tasks and pass it to Submit method of ExecutorService and add it to the List of Future Objects
ExecutorService es=Executors.newFixedThreadPool(4);
List<SampleClassimplementingCallable<String>> tasks=new ArrayList<>();
List<Future<String>> futures=new ArrayList<>();
for(SampleClassimplementingCallable<String> s:tasks)
{
//This Won't Block the Calling Thread and We will get the list of futures
futures.add(es.submit(s));
}
However, When the Futures are retrieved from the list and get method is called on indivual future object ,then the thread is blocked.

Multi-threading and queuing

I kinda got the hang of threads but now I'm confused. I don't quite understand queues at all. I created a thread pool executor which initializes a set amount of threads and each of those threads input a username(string) on a website to check if its available or not. So basically I was thinking I should queue this? like queue.add(username) and queue.remove(username) or queue.take.. So I was wondering how to do queues with thread pools and which type. SynchronousQueue, BlockingQueue, or is there a better alternative? Sorry I really dont understand queuing. Ignore the bad code. Just want it to work before I make it net
FilterUsers FU = new FilterUsers();
HtmlThread[] threads = new HtmlThread[users.length];
ExecutorService executor = Executors.newFixedThreadPool(threadNo);
for (int i = 0; i < users.length; i++) {
Runnable worker = new HtmlThread(" "+i, FU, users[i]);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()){ }
this is class HtmlThread
class HtmlThread extends Thread {
private Thread t;
private String threadName;
FilterUsers filterUsers;
String users;
public HtmlThread(String tName, FilterUsers filterusers, String user) {
this.threadName = tName;
this.filterUsers = filterusers;
this.users = user;
}
public void run() {
synchronized (filterUsers) {
try {
HtmlPage page = webClient.getPage("https://website.com/account/edit");
try {
final HtmlForm form = page.getFirstByXPath("//form[#class='adjacent bordered']");
HtmlTextInput user = form.getInputByName("username");
HtmlSubmitInput b = form.getInputByValue("Submit");
user.setValueAttribute(users);
HtmlPage page2;
page2 = b.click();
String html = page2.getWebResponse().getContentAsString();
if (page2 != null) {
if (!html.contains("that username is taken")) {
Filter.validUsers.appendText(users + "\n");
}
}
} finally {
page.cleanUp();
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
System.out.println("Thread " + threadName + " Sleeping.");
Thread.sleep(3500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + threadName + " exiting.");
}
Oh, you're concerned about returning a result. Per your comment:
I updated with code. When I do this it goes way too fast. even though
I put thread to sleep for 3.5 secs. I dont think it actually sleeps.
So I thought I should add queue to prevent loss of data or w/e
Well you should have said that in your question. You could use a queue, but Java actually has it's own mechanism for returning data. You should at least try that first.
To return a result, use the Callable interface instead of Thread/Runnable. Callable works just like Runnable except you can return a value. When you submit a Callable to an executor service, you get a Future back. Just save it and then call get() to get your result. That's it, all the hard work of making queues or synchronization is already done for you.
The only thing left is checking for InterruptedException in nearly every imaginable place. ;)
/**
*
* #author Brenden Towey
*/
public class FutureExample
{
public static void main( String[] args )
{
ExecutorService exe = Executors.newFixedThreadPool(3);
List<Future<String>> results = new ArrayList<>();
for( int i = 0; i < 5; i++ )
results.add( exe.submit( new HtmlTask() ) );
try {
for( Future<String> future : results )
System.out.println( future.get() );
} catch( InterruptedException x ) {
// bail
} catch( ExecutionException ex ) {
Logger.getLogger( FutureExample.class.getName() ).
log( Level.SEVERE, null, ex );
// and bail
}
exe.shutdown();
boolean shutdown = false;
try {
shutdown = exe.awaitTermination(10 , TimeUnit.SECONDS );
} catch( InterruptedException ex ) {
// bail
}
if( !shutdown ) {
exe.shutdownNow();
try {
exe.awaitTermination( 30, TimeUnit.SECONDS );
} catch( InterruptedException ex ) {
// just exit
}
}
}
}
class HtmlTask implements Callable<String> {
#Override
public String call()
throws Exception
{
// pretend to search a website and return some result
return "200 OK";
}
}
The ideas of queues are producers and consumers. Producers put items on the queue, which the consumer threads (usually multiple threads) pick up the items and process.
SynchronousQueue - is a queue that must have a corresponding call to take() before put() returns.
BlockingQueue - is an interface. SynchronousQueue is an implementation of this BlockingQueue
So right about now you are probably very confused. I doubt you need SynchQueue. I recommend first you should read the javadoc for BlockingQueue.
Personally, you will probably want to use ArrayBlockingQueue. You should provide a capacity. Otherwise, if the producer puts more items on the queue then you will run out of memory.
I actually dont understand why you are synchronizing on filterUsers. How does the thread entering that synchronized code block modify filterUsers? Assuming that filterUsers is some type of a List implementation (that does not seem to be the case here) that you need to synchronize on so that threads block when putting or taking elements in it, you could get rid of that synchronized code block with a BlockingQueue. The BlockingQueue would block all threads doing put() when size() reaches capacity until elements are removed with a take().
So unless your synchronized code block is on a List that needs blocking, a blocking queue is not going to be of help.

Not calling get on list of futures

I'm using a global Executor service with some fixed thread pool size. We have bunch of related tasks that we submit for execution and wait on list of futures.
Recently, we faced a high CPU utilization issue and on debugging I found that an exception occurred while calling get() on one of the item in list of futures. Current, we iterate over the list and there is a try catch surrounding the whole loop.
try{
List<Result> results = new ArrayList<>()
for(Future<Result> futureResult: futureResults{
Result result = futureResult.get();
results.add(result);
}
} catch(Exception e){
throw new InternalServiceException(e);
}
//Do something with results
Wanted to know the behaviour of other threads if get is never called on some of the items in future. I tried searching but was not able to find anything.
Also, can this behaviour trigger high CPU utilization ?
http://www.journaldev.com/1650/java-futuretask-example-program
I would still check if the future isDone as in the example above.
If you need to run other operations or want to utilize the CPU better then I would put the collector in a separate thread and perhaps just poll for results every minute or so.
Could be scheduled or handled by Thread.sleep.
Executors class provides various methods to execute Callable in a thread pool. Since callable tasks run in parallel, we have to wait for the returned Object.
Callable tasks return java.util.concurrent.Future object. Using Future we can find out the status of the Callable task and get the returned Object.
It provides get() method that can wait for the Callable to finish and then return the result.
There is an overloaded version of get() method where we can specify the time to wait for the result, it’s useful to avoid current thread getting blocked for longer time.
Future provides cancel() method to cancel the associated Callable task. There are isDone() and isCancelled() methods to find out the current status of associated Callable task.
Here is a simple example of Callable task that returns the name of thread executing the task after some random time.
We are using Executor framework to execute 10 tasks in parallel and use Future to get the result of the submitted tasks.
public class FutureObjectTest implements Callable<String>{
#Override
public String call() throws Exception {
long waitTime = (long) (Math.random()*10000);
System.out.println(Thread.currentThread().getName() + " waiting time in MILISECONDS " + waitTime);
Thread.sleep(waitTime);
return Thread.currentThread().getName() + " exiting call method.";
}
public static void main(String [] args){
List<Future<String>> futureObjectList = new ArrayList<Future<String>>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
Callable<String> futureObjectTest = new FutureObjectTest();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Starting get method of wait");
////////////get(Timeout) method///////
futureObjectList.clear();
for(int i=0; i<10; i++){
Future<String> futureResult = executorService.submit(futureObjectTest);
futureObjectList.add(futureResult);
}
executorService.shutdown();
for(Future<String> futureObj : futureObjectList){
try {
System.out.println(futureObj.get(2000,TimeUnit.MILLISECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}
}
}

Is this multithreaded iteration safe?

I have a collection and I want to spawn a number of Threads to do some heavy work on its elements. Each element of the collection must be processed one and only one time. I want to keep synchronization as minimal as possible and I came up with the following code:
//getting the iterator is actually more complicated in my specific case
final Iterator it = myCollection.terator();
Thread[] threads = new Thread[numThreads];
for( int i = 0; i < numThreads; i++ ) {
threads[i] = new Thread(new Runnable() {
public void run() {
Object obj = null;
while(true) {
synchronized (it) {
if(it.hasNext())
obj = it.next();
else
return;
}
//Do stuff with obj
}
}
});
threads[i].start();
}
for (Thread t : threads)
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
NOTE: No threads will ever modify the collection by adding or removing items while 'doing stuff with obj'
This code is quite different from examples that I found around where people tend to synchronize over the collection itself, use Collection.synchronizedStuff.., or they just synchronize over the entire iteration. During my research I also found possibly better alternatives implemented using ThreadPoolExecutor but let's forget about it for a second...
Is the code above safe considering the note 1 above? If not, why?
I wouldn't use synchronisation at all.
I would have a loop which add tasks to an ExecutorService.
ExecutorService es = Executors.newFixedThreadPool(nThreads);
for(final MyType mt: myCollection)
es.submit(new Runnable() {
public void run() {
doStuffWith(mt);
}
});
es.shutdown();
es.awaitTermination(1, TimeUnit.HOURS);
If you remove the need to create and shutdown the thread pool it is even shorter.
I think it would be better to make myCollection final and change the code as
public void run() {
Object obj = null;
for (Object e : myCollection) {
obj = e;
}
for-each creates a new Iterator in each Thread so no synchronziation is needed.

Is there a way to declare a method as a new Thread in Java

I have a program which is listening for random numbers. It is hooked up to a publisher which gives me a number and a new count and every time I get an update, I'm storing the current count for that number in a HashMap.
I also have an SSL server listening for requests. When a request comes in asking "how many 7's do we have" I just return the value in my HashMap.
Now I want to add logic that says, if we have 0 occurrences of that number, wait until we get one, and return the count at that point. However I'm struggling because of the limitation on the Thread's run method, that it must be a void. I wonder if there is anyway to just declare my method as one that always launches a new thread, or maybe a better way to handle it than what I am doing. Here is what I have:
private static volatile HashMap<Integer, Integer> occurenceMap= new HashMap<Integer, Integer>();
public synchronized static int getNumOccurrences(final Integer number) {
try {
(new Thread() {
public void run() {
Integer occurrences = occurenceMap.get(number);
if ( occurrences != null && occurrences > 0 ) {
// here I would like to just return occurences;
} else {
CountDownLatch latch = new CountDownLatch(1);
pendingList.put(number, latch);
latch.await();
// elsewhere in the code, I call countdown when I get a hit
pendingList.remove(number);
// once we've counted down, I would like to return the value
}
}
}).start();
} catch ( Throwable t ) { }
}
However, I can't put return statements in the run method. So how is this best done?
Thank you!
You'd need some kind of external structure to store the number, like this
// declared outside your runnable
final AtomicInteger result = new AtomicInteger(0);
// in your run method
// return value; // doesn't work, can't return
result.set(value);
So adding it into yours, you get this
Note that my comments start with // C:
private static volatile HashMap<Integer, Integer> occurenceMap= new HashMap<Integer, Integer>();
public synchronized static int getNumOccurrences(final Integer number) {
// C: here's a container to use inside the runnable
// C: must be final to use inside the runnable below
final AtomicInteger result = new AtomicInteger(0);
try {
// C: keep a rerefence to the thread we create
Thread thread = new Thread() {
public void run() {
Integer occurrences = occurenceMap.get(number);
if ( occurrences != null && occurrences > 0 ) {
result.set(occurences); // C: we found what we're looking for
return; // C: so get out of the run method
} else {
CountDownLatch latch = new CountDownLatch(1);
pendingList.put(number, latch);
latch.await();
// elsewhere in the code, I call countdown when I get a hit
pendingList.remove(number);
// once we've counted down, I would like to return the value
result.set(1); // C: I'm not sure what you want to return here
return; // C: but I'm sure you can figure that out...
}
}
});
thread.start(); // C: now start the thread
thread.join(); // C: join the thread, waiting for it to finish
} catch ( Throwable t ) { }
return result.get(); // C: now return the int from the container
}
Another way to result values from your Thread execution it is to use the Executors thread-pools which allow you to submit a Callable:
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
for (Job job : jobsToDo) {
futures.add(threadPool.submit(new Callable<Integer>() {
public Integer call() {
...
}
}));
}
// after submitting the jobs, you need to shutdown the queue
threadPool.shutdown();
// then you can get the results
for (Future<Integer> future : futures) {
// this will throw if your call method throws
int value = future.get();
}

Categories

Resources