Подтвердить что ты не робот

Каков наилучший способ передачи информации между потоками?

Я хочу слушать сервер, пока моя программа делает другие вещи, когда сообщение получено с сервера, я хочу его интерпретировать.

Я знаю про потоки, но не совсем уверен, как это работает. Если у меня есть поток, слушающий сервер, как я могу передать эти данные в основной поток для интерпретации? Каков наилучший способ для основного потока отправлять данные на сервер? Что такое синхронизированный модификатор?

4b9b3361

Ответ 1

Если у меня есть поток, слушающий сервер, как я могу передать эти данные в основной поток для интерпретации? Каков наилучший способ для основного потока отправлять данные на сервер?

Я использовал бы BlockingQueue. Вы определяете один BlockingQueue, например LinkedBlockingQueue. Затем ваш класс слушателя вызывает queue.take(), который будет ждать, пока ваш сервер вызовет queue.put(). Он оставляет всю синхронизацию, ждет, уведомляет и т.д. Для класса Java вместо вашего собственного кода.

Что такое синхронизированный модификатор?

Я бы немного почитал, чтобы больше узнать об этом. Это не та вещь, на которую можно ответить в коротком ИСО-ответе. Java concurrency учебник - это хорошее место для начала.

Ответ 2

Пройдите некоторые учебные пособия для понимания тем Java.

http://www.journaldev.com/1079/java-thread-tutorial

Ваша проблема, похоже, похожа на модель производителя-потребителя, вы можете использовать BlockingQueue для достижения этой задачи легко.

Java Blocking Queue

Ответ 3

Если вам нужна синхронная связь между основным потоком и потоком обработки, вы можете использовать SynchronousQueue.

Идея состоит в том, что основной поток передает данные в поток обработки, вызывая put(), а поток обработки вызывает take(). Обе операции блокировки.

Обратите внимание, что если вы хотите отправить результат, тогда ситуация может немного усложниться, поскольку основной поток должен знать, когда результат будет готов. A CountDownLatch - хороший примитив для этого. Вы можете сделать что-то вроде этого.

Сначала дайте определение структуры данных для передачи данных вокруг:

public class MethodCall {

    public final String methodName;

    public final Object[] args;

    public final CountDownLatch resultReady;

    public Object result;

    public MethodCall(String methodName, Object[] args) {
        this.methodName = methodName;
        this.args = args;
        this.resultReady = new CountDownLatch(1);
    }

    public void setResult(Object result) {
        this.result = result;
        resultReady.countDown();
    }

    public Object getResult() throws InterruptedException {
        resultReady.await();
        return result;
    }
}

Определите очередь для передачи данных вокруг, видимых обоими потоками:

public SynchronousQueue<MethodCall> methodCalls = new SynchronousQueue<MethodCall>();

Чтобы сделать вызов из основного потока в поток обработки и дождаться результата:

MethodCall call = new MethodCall(methodName, args);
methodCalls.put(call);
Object result = call.getResult();

В потоке обработки, например, в методе run(), вы можете:

for (;;) {
    MethodCall call = methodCalls.take();
    Object res = processStuff(call.methodName, call.args);
    call.setResult(res);
}

Где processStuff реализует вашу логику. Конечно, вы также должны иметь дело с исключениями, иметь дело с случаями выхода, изменить MethodCall на более конкретные вещи, чем methodName и args и Object return и т.д.