views:

101

answers:

4

I am having a program of chat written on Java and using one Thread,one client and several clients that could come up online and disconect. Every new user can see and talk to everyone and everyone sees him. Now,I search a way of making several conversetion there. Something like: the first one and second one are in a private room,the third one and the forth one in a private room.... I thought to do so with ThreadGroup but for some reason I can't find a document that can explain me if this is relevent or not... Anyway,is it the right way? And how should I exactly do that?

+2  A: 

If I understood your application correctly, I'm not sure you need threads (unless that's a requirement).

Simply have each user register to a room - this can be a simple Map with the rooms as keys and a list of users as a value. Once you need to dispatch a message to a room, simply take the entire list of users in that room (discounting the sending user) and send out the message to each one.

If you want to use threads, you'll need a slightly more sophisticated model, something along the lines of a manager thread per room, this can easily be done with a simple thread pool and an ExecutorService, like so:

ExecutorService es = Executors.newFixedThreadPool(3); // or whatever
for (Runnable r : someRunnableList)
{
    es.execute(r);
}

(I strongly advise that if you employ concurrency in your application, take great care to ensure you are not introducing any bugs. Fixing concurrency bugs is not a pleasant ordeal).

Yuval A
A: 

Although not quite the answer to the question you're asking, if I were you I wouldn't start from here. Unless you have a specific reason for choosing threads and you are comfortable with multi-threaded programming in Java then you might consider an evented approach using non-blocking IO and a single threaded model. The java.nio package (introduced since Java 1.4) provides the underpinnings for doing this.

You could also consider one of the many battle hardened frameworks for implementing your solution such as Grizzly or Mina. The advantage of using a framework is that you can build single or safe multi-threaded IO applications (which can be a highly non-trivial undertaking) with the support of active communities and proven solutions.

bjg
A: 

Threading is probably not your optimal solution for this problem. You might find that threading introduces new issues that will just sidetrack you from getting your application functioning.

As you've described it, what would probably work is to represent each user with an instance of some class, call it ChatUser (for lack of a better term at the moment), and embed the logic for who is allowed to talk to who into the methods of ChatUser. For example, each instance would have an attribute that says what room that user is in, and when the user wants to say something, the method that handles that checks the other instances of ChatUser, and only sends the string to those that have a matching room attribute.

JustJeff
Well,I had to use threads for this project,then I assume that you're idea is quite good for me....I will defently use it,Thank you!
Inbal
A: 

I guess although you could implement that using only one thread, it would be certainly cumbersome because all request will be processed sequentially, and when network is involved which has quite a large latency and prone to things like timeout, your app. can easily become very unresponsive. Let's say somebody gets disconnected from the internet. If you had only one thread, your entire app will hold up until the timeout is reached and you discover something is wrong with this client! Even if somebody decides to be quiet for a while, you'll have trouble (it's probably easily work-aroundable, but still extra complexity).

So although not central, use of multiple thread is very much recommendable.

However, use of ThreadGroup is discouraged by the concurrency expert group so you should probably not use it.

I'm not clear what your current app's design is. If you could tell us a little bit more, we might be able to help you more.

One simple approach will be using a combination of HTTP server and client. So each client is also a server, and passes its callback address (for its server) to the central server upon connection. Subsequently, client will push new messages to the central server through HTTP POST, and the central server will push these messages to clients through HTTP POST.

If you'd chose such design, threading is unavoidable.. The thread which will make the HTTP POST request can be single threaded (per JVM), but the thread that will receive the HTTP request can not be the same thread (it is not impossible, but I don't think it's feasible).

So the easiest thing would be to embed tokens to identify the group, and use this like this (just meant for VERY basic illustration!!!):

class Chat {
    private final ConcurrentMap<String,Set<URI>> rooms;
    {
        rooms = new ConcurrentHashMap<String,Set<URI>>();
    }

     public void connect(String roomKey, URI callbackAddr){
         Set<URI> users = rooms.get(roomKey);
         if(users==null){
             rooms.putIfAbsent(roomKey,new ConcurrentSkipListSet<URI>());
         }
         users = rooms.get(roomKey);
         users.add(callbackAddr);
     }

     public void say(String roomKey, String message){
         if(rooms.get(roomKey)==null){
             throw new RuntimeException("Room " + roomKey + " does not exist.");
         }

         for(URI dest : rooms.get(roomKey)){
             HTTPPoster.postMessage(dest, roomKey, message);
         }
 }

}

You'll have a similar piece on your client.

Enno Shioji