как использовать уведомления и ждать - PullRequest
10 голосов
/ 06 мая 2011

Может ли ожидание / уведомление использоваться в одном потоке? Я имею в виду, что у меня есть слушатель, и в тот момент, когда его слушают, я хочу, чтобы поток мог выполнять его работу. Как я могу это сделать?

ОБНОВЛЕНИЕ: Мои данные записываются в базу данных ... и записываются каждый раз, когда вызывается слушатель. Теперь созданный мной поток читает эти данные и отправляет их куда-то .... Далее ... я получаю некоторые другие данные и делаю то же самое .... Другой поток должен знать, какие последние данные он прочитал, чтобы он мог начать читать с того места, где он ушел ....

Посмотрите здесь: используя ожидание и уведомление в одном потоке Вот так выглядит моя проблема. Спасибо

У меня есть следующее:

synchronized (syncToken)
{
    try {
        syncToken.wait();

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
System.out.println("MyThread: " + s);

в MyThread .... поэтому, когда я делаю

MyThread t = new MyThread(syncToken);
t.start();

Я положил свою ветку на ожидание ... да?

И когда я делаю это:

syncToken.notify();

Я возвращаю свою нить в нужное русло .... но выполнение следующей строки выполняется после wait ()?

Я имею в виду это: System.out.println("MyThread: " + s); ????

Когда вы уведомляете thred, он продолжает выполнение со строки после wait () ??? Thx

Ответы [ 2 ]

14 голосов
/ 06 мая 2011

Ниже приведен простой пример параллелизма между двумя разными потоками. В этом примере основной поток запускает поток MyThread и каждые 3 секунды устанавливает данные для экземпляра MyThread, а затем MyThread печатает его. Идея состоит в том, чтобы иметь синхронизированный объект, который вы wait на нем и notify в конце использования другим потокам, чтобы они могли его использовать:

Test.java:

package stack;

public class Test {
    public static void main (String args[])
    {
        Object syncToken = new Object();
        MyThread t = new MyThread(syncToken);
        t.start();
        for (int i = 0; i < 10; i++)
        {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized(syncToken)
            {
                t.setText("Iteration " + i);
                syncToken.notify();
            }
        }
    }
}

MyThread.java:

package stack;

public class MyThread extends Thread{

    String s;
    Object syncToken;
    public MyThread(Object syncToken)
    {
        this.s = "";
        this.syncToken = syncToken;
    }

    public void run()
    {
        while(true) // you will need to set some condition if you want to stop the thread in a certain time...
        {
            synchronized (syncToken)
            {
                try {
                    syncToken.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("MyThread: " + s);
        }
    }

    public void setText(String s)
    {
        this.s = s;
    }
}

В этом примере основной поток устанавливает строку (каждые 3 секунды), а поток MyThread печатает ее.

Адаптируйте его под свои нужды, это не должно быть слишком сложно.

3 голосов
/ 07 мая 2011

У меня была похожая проблема.Я создал арбитр, используемый двумя потоками (в вашем случае это может быть поток слушателей и поток ваших задач): listener:

arbiter.waitConsumer();
// prepare data
arbiter.dataLoaded();

поток задач:

while(true){
  arbiter.waitProducer();
  // consume data
  arbiter.dataConsumed();
}

арбитр:

public class Arbiter {
private boolean dataLoaded = false;
public synchronized void waitProducer(){
    while(!dataLoaded){
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public synchronized void waitConsumer(){
    while(dataLoaded){
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public synchronized void dataLoaded(){
    dataLoaded = true;
    notify();
}public synchronized void dataConsumed(){
    dataLoaded = false;
    notify();
}}

Слушатель и задача синхронизируют себя с монитором арбитров.Возможно, вы можете вызвать свою очередь арбитра или канал и сохранить дату для ее использования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...