I'm working on updating a Java program that has to call a Web Service. The application is a Corporate phonebook (white pages) that uses the Sun LDAP Directory server. One option in the program calls a Web Service to get external (non-LDAP) data about a person. The application would wait if the Web Service was either slow or not available, eventually timing out. The timeout was too long for the end-user.
The requirement was to have the application call the Web Service with the option of setting a specific timeout.
I reviewed my Java books on threading, searched the web and tried to write a test Java app that would create a Thread, have the new Thread call the Web Service and stop if the Thread took too long. I tried using various combinations of
wait(millseconds)
and
notify()
to make something happen. No luck. I asked a friend "What am I doing wrong"?
His anwser was
java.util.concurrent.FutureTask
Thanks again to Brian Doherty for the advise.
The java.util.concurrent.* package is new in the Java SE 5.0 release. I found a great example of using FutureTask in Core Java 2 Volume II - Advanced Features, Seventh Edition Chapter 1. Multithreading. The get(timeout_value,timeout_unit) method was exactly what I needed. It was soooooo much easier to implement a test program with the java.util.concurrrent package then by manually trying to make wait()/notify() work. Here's my test program which has a timeout value set to expire before the work (sleeping) is complete:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class testFutureTask
{
Perform perform = null;
FutureTask task = null;
Thread thd = null;
public testFutureTask()
{
}
public static void main(String[] args)
{
testFutureTask test = new testFutureTask();
test.begin();
}
private void begin()
{
String answer = null;
perform = new Perform("what is the question");
task = new FutureTask(perform);
thd = new Thread(task);
thd.start();
System.out.println("\nPerforming the Task, (please wait) ... \n");
try
{
// answer = task.get(); // run until complete
answer = task.get(5000,TimeUnit.MILLISECONDS); // timeout in 5 seconds
}
catch (ExecutionException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
answer = "got interrupted.";
}
catch (TimeoutException e)
{
answer = "tired of waiting, timed-out.";
}
System.out.println(answer);
return;
}
}
class Perform implements Callable
{
private String input = null;
private String output = null;
public Perform(String input)
{
this.input = input;
}
public String call() throws Exception
{
output = "The response to '" + input + "' is 42";
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
System.out.println("Perform::call(), sleep interrupted.");
}
return output;
}
}