31

How do threads that rely on one another communicate in Java?

For example, I am building a web crawler with threads that need data that comes from other threads.

tipu
  • 9,464
  • 15
  • 65
  • 98

4 Answers4

31

Below is example for Inter thread communication:

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]);
        }
    }
}
CSchulz
  • 10,882
  • 11
  • 60
  • 114
Sujay
  • 311
  • 3
  • 2
  • 5
    This example is used here: [http://www.tutorialspoint.com](http://www.tutorialspoint.com/java/java_thread_communication.htm) – Malus Jan Jul 03 '16 at 20:59
26

That depends on the nature of the communication.

  • Is it duplex (ie A talks to B and B talks to A)?
  • Is it communication of data or communication of completion?

and so on.

The simplest and most advisable form of inter-thread communication is simply to wait for the completion of other threads. That's most easily done by using Future:

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

The second task won't execute until the first completes.

Java 5+ has many concurrent utilities for dealing with this kind of thing. This could mean using LinkedBlockingQueues, CountDownLatch or many, many others.

For an in-depth examination of concurrency Java Concurrency in Practice is a must-read.

Hearen
  • 7,420
  • 4
  • 53
  • 63
cletus
  • 616,129
  • 168
  • 910
  • 942
  • The threads don't go both ways, one thread waits for the result of another but not vice versa. Admittedly I'm a bit intimidated by the use of ExecutorService and Future, as I've never heard of them before. Is there another method of interthread communication not using Future and ExecutorService? – tipu Jan 31 '10 at 04:50
  • 1
    There's no need to be intimidated by `ExecutorService` and `Future`. They are reasonably simple and should take less than 2 hours to learn. Using `Future`s is easier than the standard queue classes, and a lot easier than rolling your own queue classes using `wait()` and `notify()`. – finnw Jan 31 '10 at 05:04
  • @cletus, -1 for calling `Future.get()` from within a task in a *fixed* thread pool. The danger there should be obvious. – finnw Jan 31 '10 at 05:08
  • @finnw: of course theres a danger but in the absence of the requirements for the communication or a better description you can't possibly suggest a method without danger. – cletus Jan 31 '10 at 05:16
  • This particular danger can be rectified by using a cached thread pool. – finnw Jan 31 '10 at 05:49
  • @finnw: and a cached thread pool can create other problems. That's kinda the point. – cletus Jan 31 '10 at 15:51
  • Please give an example. Here's a description of the kind of problem I was referring to: http://weblogs.java.net/blog/2008/11/25/tricks-and-tips-aio-part-1-frightening-thread-pool – finnw Jan 31 '10 at 16:55
  • @finnw: cached thread aren't limited. I've had a system fail because it created 30K+ threads because of this. On the same system, capping it to 2,000 threads not only worked but had significantly more overall throughput than the times the system didn't fall over with a cached thread pool. My point is that blanket statements like stating Future.get() in a fixed thread pool is dangerous in a vague question is naive and simply can't be made with any certainty. – cletus Jan 31 '10 at 21:29
  • See also: [Is “Java Concurrency In Practice” still valid?](http://stackoverflow.com/questions/10202768/is-java-concurrency-in-practice-still-valid). – malana Sep 02 '15 at 23:04
2

Take a look at java.util.Observer/java.util.Observable. They are exactly what you are looking for.

Kieveli
  • 10,944
  • 6
  • 56
  • 81
David Sowsy
  • 1,680
  • 14
  • 13
  • 6
    Using observers will not work, as they don't cross threads (all Observer callbacks will be called from the Observable's thread). "Note that this notification mechanism is has nothing to do with threads." from http://docs.oracle.com/javase/6/docs/api/java/util/Observable.html – Wander Nauta Jul 31 '13 at 08:00
0

You could use 2 ExecutorServices, submit a Callable implementation to service A that knows about follow on service B. When the Callable has completed it's work, it submits a new task to service B that does something additional with the results.

You could use a CountDownLatch or some other barrier if you need to perform additional work once all items have been processed in both services.

The ExecutorService api is pretty straight forward, for the most part you'll probably be using something like .newFixedThreadPool(int threads) and submitting Runnables/Callables to it.

Chris
  • 1