Async (Non-blocking) programming with Java
Following on from my last post, where i explore doing Async with C++0x, in this one i try to accomplish the exact same thing with Java.
So first of all, before i say anything else, to me Java is first love and to some extent I still love the idea of writing anything in Java. However there are things that i have come to appreciate in other languages such as C++. So in case you are wondering, why the disclaimer? well when trying to do some Async stuff with Java, i found it to be a bit more complicated then what it was in C++. I honestly never ever imagined myself saying this, but yes it is true, i tried really hard to blame it on the tutorials that i found or my own thinking, but i must accept it for what it is.
So say, we have a shop and we are counting the cash at the end of the day to know how much we earned. A colleague will provide some help, by counting the 5$ notes. So how do we go about this?
import java.util.concurrent.Future;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Async{
/*
think of callable as a Runnable that can return a value
unfortunately i have not been able to get a solution, where
we can simply just call a method asynchronously, it seems a
Callable class is a way to go.
*/
static class CountFiveNotes implements Callable<Integer>
{
//think of this as the run method that can return a value
@Override
public Integer call()throws Exception
{
int total = 0;
for(int fiveCounter = 0;fiveCounter<100;fiveCounter++)
{
total+=5;
}
return total;
}
}
public static void main(String args[])
{
//create a pool of 10 threads, it doesnt matter for this problem of how many
ExecutorService executor = Executors.newFixedThreadPool(10);
Callable<Integer> fiveNoteCounter = new CountFiveNotes();
/* this is where we are making the async call to the CountToFiveNotes
Future is very useful as we can use it to retrieve the value of a
callable and check if a callable has finished executing!
*/
Future<Integer> fiveNoteTotal = executor.submit(fiveNoteCounter);
int ourTotal =0;
for(int counter=0;counter<10000000;counter++)
{
ourTotal+=counter;
if(fiveNoteTotal.isDone())
{
System.out.println("This is where we got up to:"+counter);
try{
ourTotal+=fiveNoteTotal.get();
System.out.println("Total so far:"+ourTotal);
}catch(Exception e){e.printStackTrace();}
break;//lets take a short break
}
}
executor.shutdown();
}
}
javac Async.java
but i cant see a reason why this code wouldn't work in Eclipse or Netbeans.
http://www.vogella.com/articles/JavaConcurrency/article.html
http://www.ibm.com/developerworks/java/library/j-jtp04186/index.html
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html
So first of all, before i say anything else, to me Java is first love and to some extent I still love the idea of writing anything in Java. However there are things that i have come to appreciate in other languages such as C++. So in case you are wondering, why the disclaimer? well when trying to do some Async stuff with Java, i found it to be a bit more complicated then what it was in C++. I honestly never ever imagined myself saying this, but yes it is true, i tried really hard to blame it on the tutorials that i found or my own thinking, but i must accept it for what it is.
Problem
Given how boring my problem definition was in the last post, i will try to make this more exciting in this one.So say, we have a shop and we are counting the cash at the end of the day to know how much we earned. A colleague will provide some help, by counting the 5$ notes. So how do we go about this?
- Start counting all the notes
- While we are counting the colleague will start counting his 5$ notes
- At some point he will finish and tell us what his total is
- We will compare that with the total we have and take a short break
Solution
import java.util.concurrent.Callable;import java.util.concurrent.Future;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Async{
/*
think of callable as a Runnable that can return a value
unfortunately i have not been able to get a solution, where
we can simply just call a method asynchronously, it seems a
Callable class is a way to go.
*/
static class CountFiveNotes implements Callable<Integer>
{
//think of this as the run method that can return a value
@Override
public Integer call()throws Exception
{
int total = 0;
for(int fiveCounter = 0;fiveCounter<100;fiveCounter++)
{
total+=5;
}
return total;
}
}
public static void main(String args[])
{
//create a pool of 10 threads, it doesnt matter for this problem of how many
ExecutorService executor = Executors.newFixedThreadPool(10);
Callable<Integer> fiveNoteCounter = new CountFiveNotes();
/* this is where we are making the async call to the CountToFiveNotes
Future is very useful as we can use it to retrieve the value of a
callable and check if a callable has finished executing!
*/
Future<Integer> fiveNoteTotal = executor.submit(fiveNoteCounter);
int ourTotal =0;
for(int counter=0;counter<10000000;counter++)
{
ourTotal+=counter;
if(fiveNoteTotal.isDone())
{
System.out.println("This is where we got up to:"+counter);
try{
ourTotal+=fiveNoteTotal.get();
System.out.println("Total so far:"+ourTotal);
}catch(Exception e){e.printStackTrace();}
break;//lets take a short break
}
}
executor.shutdown();
}
}
Compiling the code above
I was too lazy to do this in an IDE, so i just compiled it over the command line using,javac Async.java
but i cant see a reason why this code wouldn't work in Eclipse or Netbeans.
References used
http://www.vogella.com/articles/JavaConcurrency/article.html
http://www.ibm.com/developerworks/java/library/j-jtp04186/index.html
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html
Comments