How do I delay tasks , so never more than one a second?

Im using Java 1.5 I currently have a single thread that as aprt of its processing sends urls to a website, the terms of service of the website state that there must be a 1 second delay between each request. I dont want to break that condition but I want to keep the application as fast as possible.

What's the simplest way to achieve this, I looked at DelayQueue and thought of adding another thread that took items of the queue and processed them but I couldnt see how this could work because the delay if any between processing the urls is

1 SECOND - (TIME LAST URL SENT - TIME URL RECIEVED ) so I cant work out an absolute delay when I add to the queue, and besides I would prefer to keep single threaded if possible.

this is an urgent problem, thanks for any help

[794 byte] By [paultaylora] at [2007-11-27 5:18:28]
# 1
DelayQueue seems like overkill, or not even the right tool for exactly this job.Why not just use a normal collection, and have a loop that takes a URL from the collection, gets it, and then does Thread.sleep(1000)?
paulcwa at 2007-7-12 10:41:37 > top of Java-index,Java Essentials,Java Programming...
# 2
Because that would intruduce unecessary delay, there might be a one second delay between sending a request and getting a response anyway in some cases, so i would endup delaying by 2 seconds
paultaylora at 2007-7-12 10:41:37 > top of Java-index,Java Essentials,Java Programming...
# 3
So sleep for (THEN + 1 - NOW) seconds. Unless that's negative.
DrClapa at 2007-7-12 10:41:37 > top of Java-index,Java Essentials,Java Programming...
# 4

Ok, thanks very much that works.

I have a followup question, actually my code was originally multithreaded but I changed to single threaded to try and meet the terms of service of the webserver. Now i want to revert back to multithreaded keeping the delay code added because sometimes the responses are taking a few seconds, so if it was multithreaded another thread could send another requested one second after the first thread whilst that thread was waiting for a response to speed up throughput.

But I dont think the solution will work in this case even though the method is sychronized because as soon as one Thread sleeps, another thread can interrupt it and send a response itself before the thread has finished sleeping (i.e before the second is up) How can I solve this, code exerpt below:

thanks paul

private static volatile DatequerySentDate = new Date();

private static SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSS");

private static long DELAY_IN_MILLISECONDS = 1000;

public static synchronized Metadata performQuery() throws NetworkException, InvalidQueryException

{

Date currentDate = new Date();

long delay = currentDate.getTime() - querySentDate.getTime();

if( delay < DELAY_IN_MILLISECONDS)

{

try

{

Thread.sleep(DELAY_IN_MILLISECONDS - (delay ));

}

catch(InterruptedException ie)

{

return null;

}

}

querySentDate = new Date();

Metadata metadata = null;

URL url = null;

BufferedInputStream bis = null;

HttpURLConnection uc = null;

try

{

url = new URL(getBaseQueryUrl() + sb.toString());

uc = (HttpURLConnection) url.openConnection();

int responseCode = uc.getResponseCode();

if (responseCode != HttpURLConnection.HTTP_OK)

{

throw new InvalidQueryException();

}

bis = new BufferedInputStream(uc.getInputStream());

JAXBContext jc = JAXBContext.newInstance("com.test.dataformat");

Unmarshaller um = jc.createUnmarshaller();

metadata = (Metadata) um.unmarshal(bis);

}

catch (IOException e)

{

throw new NetworkException("Unable to connect");

}

return metadata;

}

paultaylora at 2007-7-12 10:41:37 > top of Java-index,Java Essentials,Java Programming...