0

I have a class which holds a collection of references to workers threads that receive objects via TCP (1 per client).

I'm trying to make a method getMessage() in my class which waits until any of the workers threads got a message and returns it.

What I got right now is a polling-system:

public Object getMessage() {  
    while (true) {  
        for (Worker w : workers.values())  
             if (w.msgNumber() != 0)  
                 return w.getLastMsg();  
        Thread.sleep(100);  
    }  
}

It works, but I don't think it's very scalable.

I know I can do a wait(timeout) on each worker, but the problem stays the same.

Is there some kind of wait/notify mechanism which waits for multiple threads?

Jason Sturges
  • 15,855
  • 14
  • 59
  • 80
Krisprolls
  • 3
  • 1
  • 3
  • 1
    You want to implement a version of the producer/consumer paradigm. This link is a good intro to doing so in Java: http://www.java2s.com/Code/Java/Threads/Producer-Consumer.htm Searching for the terms "producer consume java" yields many more helpful pages. – dlev Jun 22 '12 at 21:12
  • You could have the worker threads notify() the main thread when they have processed something. In that case you can use wait() (without the timeout) on the main thread and it will wake up when something needs to be done. – Jochen Jun 22 '12 at 23:12

2 Answers2

4

You could look at using a blocking queue for communications between threads. The worker thread would insert into the queue, while the getMessage() function pulls a message from the queue.

Kenster
  • 23,465
  • 21
  • 80
  • 106
  • Thank you for your response. Unfortunately, the workers cannot know each other, or the class above them (they must be able to work without it). I'm trying to make something low-coupled. – Krisprolls Jun 22 '12 at 21:25
  • 2
    Well, the workers don't need to know about each other or the "class above them". They just access to a queue object which they can stuff messages into, or an API which they can call that stuffs messages into a queue for them. – Kenster Jun 22 '12 at 21:28
  • 1
    Exactly. Use a high-level class designed for this task, not `wait()` and `notify()`. If you don't understand how to apply the high-level concurrency utilities, how can you possibly use the low-level primitives? The only dependency the worker would have is on [`java.util.Queue`](http://docs.oracle.com/javase/7/docs/api/java/util/Queue.html). If you want the client to be throttled when the consumer can't keep up, you could switch to [`java.util.concurrent.BlockingQueue`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) – erickson Jun 22 '12 at 21:44
0

How about something like:

   try {
        ServerSocket srv = new ServerSocket(port);

        // Wait for connection from client.
        while (true) {
            System.out.println("Listening...");
            // Waits for connection
            new Thread(new ServerWorkerThread(srv.accept())).start(); 

        }
    } catch (IOException e) {
      //handle
    }
Jeremy
  • 2,870
  • 3
  • 23
  • 31