I’m having a threading issue..
I’m doing a lookup using an inner class..I’ve been reading up on how to do this properly and everything points at using a field..in my case ” boolean verify”.
Basically if the object is there. I declare the field true and return the value. The problem is, during performance testing the same method in the same object is being called in several threads at the same time and the effects have been funny. (I’m guessing because of the pause() (which waits 10ms))
So in thread A..the objects there so it declares the field true..waits 10ms..
in thread B..the objects not there but because of the wait and that the same field is being accessed it returns a true anyway.
I’m in trouble here 🙁
Does anyone know of a better way to do this?
boolean verify;
public boolean lookupAndVerify(String id) throws InterruptedException
{
final String key = id;
PastryIdFactory localFactory = new rice.pastry.commonapi.PastryIdFactory(env);
final Id lookupKey = localFactory.buildId(key);
Past p = (Past) apps.get(env.getRandomSource().nextInt(apps.size()));
p.lookup(lookupKey, new Continuation<PastContent, Exception>()
{
public void receiveResult(PastContent result)
{
P2PPKIContent content = (P2PPKIContent) result;
if(content !=null){
verify = true;
}
}
public void receiveException(Exception result)
{
System.out.println("Error looking up " + lookupKey);
}
});
pause();
return verify;
}
I think you could use a bit of research into asynchronous calls. Pausing for a certain number of milliseconds is not a safe way to ensure that your callback has been called, and as you said, making
verifya field will not work if the object is shared by multiple threads.One option you could use is a
Future<Boolean>(in this case,SettableFuture<Boolean>from the Guava libraries is convenient):A
Future<T>is a concurrency construct that will have a value some time in the future. As soon as you ask for its value, however, it will block until it has a value.Edit
If for some reason you can’t pull in Guava, a slightly less intuitive solution is to use a
BlockingQueue<Boolean>with a capacity of 1:If you’re going to do this, it’s worth encapsulating the queue in a class with a more readable API.