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

Межпоточная связь в java

Как потоки, которые полагаются друг на друга, обмениваются данными на Java?

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

4b9b3361

Ответ 1

Это зависит от характера общения.

  • Это дуплекс (то есть, А говорит с В, а Б говорит с А)?
  • Это передача данных или передача завершения?

и так далее.

Самая простая и наиболее рекомендуемая форма связи между потоками - это просто ожидание завершения других потоков. Это проще всего сделать с помощью Future:

ExecutorService exec = Executors.newFixedThreadPool(50);
final Future f = exec.submit(task1);
exec.submit(new Runnable() {
    @Override
    public void run() {
        f.get();
        // do stuff
    }
});

Второе задание не будет выполнено, пока не выполнится первое.

Java 5+ имеет много параллельных утилит для работы с такими вещами. Это может означать использование LinkedBlockingQueue s, CountDownLatch или многих, многих других.

Для углубленного изучения параллелизма Java Concurrency на практике необходимо прочитать.

Ответ 2

Ниже приведен пример взаимодействия между потоками:

public class Main {
    public static void main(String[] args) {
        Chat m = new Chat();
        new T1(m);
        new T2(m);
    }
}

class Chat {
    boolean flag = false;

    public synchronized void FromSam(String msg) {
        if (flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(msg);
        flag = true;
        notify();
    }

    public synchronized void FromJam(String msg) {
        if (!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(msg);
        flag = false;
        notify();
    }
}

class T1 implements Runnable {
    Chat m;
    String[] s1 = { "Hello Jam", "How are you ?", "I am also doing fine!" };

    public T1(Chat m1) {
        this.m = m1;
        new Thread(this, "Sam").start();
    }

    public void run() {
        for (int i = 0; i < s1.length; i++) {
            m.FromSam(s1[i]);
        }
    }
}

class T2 implements Runnable {
    Chat m;
    String[] s2 = { "HI Sam", "I am good,And U ?", "ha haa" };

    public T2(Chat m2) {
        this.m = m2;
        new Thread(this, "Jam").start();
    }

    public void run() {
        for (int i = 0; i < s2.length; i++) {
            m.FromJam(s2[i]);
        }
    }
}

Ответ 3

Взгляните на java.util.Observer/java.util.Observable. Они именно то, что вы ищете.

Ответ 4

Вы можете использовать 2 ExecutorServices, передать реализацию Callable для службы A, которая знает, что нужно следовать в службе B. Когда Callable завершила работу, она отправляет новую задачу в службу B, которая делает что-то дополнительное с результатами.

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

ExecutorService api довольно прямолинейный, по большей части вы, вероятно, будете использовать что-то вроде .newFixedThreadPool(int threads) и передавать ему Runnables/Callables.