2013-04-30 3 views
0

Я работаю над многопоточным проектом, для которого я хотел бы иметь класс, который задерживает вызовы методов из всех потоков за некоторый период восстановления после каждого вызова метода. Например, если класс:Задержка вызовов объекту без принудительного отключения текущего потока

public class Printer { 

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

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

} 

Я хотел бы три звонка в print() печатать три значения каждый второй части. Хотя это можно сделать довольно легко с Thread.currentThread().sleep(ms), catch заключается в том, что я бы хотел, чтобы вызывающий поток продолжал его выполнение. Для уточнения, учитывая следующий пример:

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();  
} 

Я хотел Foo, работает Foo и работает бар немедленно напечатать (в любом порядке), а затем бар второй позже. Кто-нибудь знает о хорошем подходе к таким функциям?

EDIT:

Printer класс является самым простым примером этого вопроса, что я мог думать, но на самом деле, этот класс будет иметь целый ряд методов, которые все требуют общего времени восстановления. Вызов одного из этих методов задерживает выполнение других за это время. Класс может даже иметь подклассы с методами, которые используют этот же кулдаун.

+0

Выглядит как вид таймера с обработкой событий. В большинстве настольных графических интерфейсов реализованы такие вещи. Может быть, вы можете получить вдохновение оттуда. – SpaceTrucker

ответ

2

Класс вашего принтера;

Очереди для строк

Рабочего потока

-

Когда рабочий поток заканчивает его остывать, он проверяет что-нибудь на очереди, если ничего, он останавливается.

Когда что-то добавляется в очередь, если рабочий поток остановлен, отпустите его снова.

+0

Хороший вопрос, который работает в этом примере, но я не уверен, как он будет работать в целом (см. Мое недавнее редактирование). – wheels

+0

Рабочий поток вызывает кулдаун, а не метод добавления материала в рабочую очередь. –

+0

Я все еще не уверен, как это будет работать в целом. Что, если у «Принтера» также был метод с кулдауном, который не принимал никаких параметров? Что будет добавлено в очередь?Что делать, если у принтера был подкласс, методы которого не могут добавлять значения в эту очередь? – wheels

0

Сделать вызываемый поток использовать Thread.sleep. Например, создайте класс, который реализует Runnable. Кроме того, этот класс реализует Cooldown. Кулдаун может иметь метод doCooldown, который просто вызывает Thread.sleep в течение указанного количества времени. В случае необходимости, вы можете просто иметь переменную в Runnable класса, который cooldownTime вместо ...

+0

Разве это не только разрешает кулдауну работать в этом потоке? Даже если один поток спал, он не гарантирует, что другие потоки не смогут вызвать 'print()'. – wheels

0

Вы можете написать свой кулдаун метод, как это:

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

Кроме того, если вы хотите напечатать бар через секунду после этого измените метод print() так, чтобы он сначала ожидал, а затем печатал():

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

Первое предложение предотвратит ** запуск foo ** от печати сразу, так как ему придется подождать секунду для 'wait (ms)' для завершения. – wheels

+0

В этом случае вы можете использовать system.out.print() для печати foo –

+0

Я не уверен, что я следую. Обратите внимание на редактирование, «Принтер» предназначен для примера, это идея предотвращения того, чтобы вызывающий поток спал, что важно для меня. – wheels

Смежные вопросы