wheels
wheels

Reputation: 198

Delaying calls to an object without forcing the current thread to sleep

I'm working on a multithreaded project for which I would like to have a class that delays method calls from all threads for some cooldown period after each method call. For example, given the class:

public class Printer {

    protected void cooldown(long ms) {
        // ???
    }

    public synchronized void print(String str) {
        System.out.println(str);
        cooldown(1000);
    }

}

I would like three calls to print() to print the three values each one second apart. While this could be done fairly easily with Thread.currentThread().sleep(ms), the catch is that I would like the calling thread to continue its execution. To clarify, given the following example:

public static void main(String[] args) {
    final Printer p = new Printer();

    new Thread(new Runnable() {
        public void run() {
            p.print("foo");
            System.out.println("running foo");
        }
    }).start();

    new Thread(new Runnable() {
        public void run() {
            p.print("bar");
            System.out.println("running bar");
        }
    }).start();    
}

I would like foo, running foo, and running bar to print immediately (in any order), followed by bar a second later. Does anybody know of a good approach to get this kind of functionality?

EDIT:

The Printer class is the simplest example of this issue that I could think of, but in reality, this class will have a variety of methods that all require a shared cooldown. Calling one of these methods will delay execution of the others during that time. The class might even have subclasses with methods that share this same cooldown.

Upvotes: 0

Views: 259

Answers (3)

Vineet Singla
Vineet Singla

Reputation: 1677

You may write your cooldown method like this:

 private void cooldown(long ms) {
   try {
    wait(ms);
} catch (InterruptedException e) {
    e.printStackTrace();
}

Also if you want to print bar a second later then change your method print() so that it first waits and then print():

public synchronized void print(String str) {
        cooldown(1000);
        System.out.println(str);        
    } 

Upvotes: 0

Kyle
Kyle

Reputation: 4278

Make the called thread use Thread.sleep. For example, create a class that implements Runnable. Additionally make that class implement Cooldown. Cooldown can have a method doCooldown that just calls Thread.sleep for the specified amount of time. If need be, you can just have a variable in the Runnable class that is cooldownTime instead...

Upvotes: 0

Pork 'n' Bunny
Pork 'n' Bunny

Reputation: 6731

Your printer class needs;

A queue for the strings

A worker thread

--

When the worker thread finishes it cool down, it checks for anything on the queue, if nothing, it stops.

When something is added to the queue, if the worker thread has stopped, kick it off again.

Upvotes: 2

Related Questions