How to have 2 Threads Talk To Each Other?
I'm currently making a IRC bot in Java (I know, there are frameworks out there) and I'm trying to have it connect to multiple servers. The problem I'm having with this is not the connecting part, I'm just running my Connect class in x amount of threads. Each thread will connect the bot to the server/port specified. Now my problem is that when certain text is outputted by a user the bot is supposed to message the channel saying "you typed this command" (for an example). Now I would want the bot to message ALL servers saying "you typed this command". This is simply just an example (which is why it doesnt make much sense).
Connect f = new Connect(irc.freenode.net, 6667);
Thread ft = new Thread(f);
ft.start();
Connect q = new Connect(irc.quakenet.org, 6667);
Thread qt = new Thread(q);
qt.开发者_如何学运维start();
Now having the example code above, I would want one thread to talk to the other when certain text is typed. Something like:
if (lineReader.substring(lineReader.indexOf(":"), lineReader.length()).equals("hello")) {
message both servers "Hello World!"
}
If anyone could help, I'd greatly appreciate it. Thanks!
I think a simple approach would be an Observer pattern where each thread knows about all the other threads
You should give each thread a Queue of incoming messages that other threads can push to in an asynchronous manner; java.util.concurrent.ConcurrentLinkedQueue would probably be a good class to use for that.
You will then need a single MessageSender class instance that has references to all your threads. If a thread wants to send a message to all other threads, it would call send(msg) on this global MessageSender object, and it in turn will then iterate over all threads and push the message to their respective queues (skipping the thread of the sender).
The threads themselves can then check their own queue from time to time (depending on whatever other logic they may be executing as well) and remove messages once they have handled them.
The messagePasser solution will not work because string objects in java are passed by value, not by reference.
From your description I take that each of the threads is waiting for a message from some other user on the chat. Waiting means it calls some network method which returns only when a message arrives. As soon as that message arrives, the thread (optionally) generates an answer, posts it and then continues waiting. That why you have multiple threads, right?
That means, however, that threads can only send something after they received something. Because only then they are woken up from their waiting state. That means that it's not workable to "broadcast" the command response to all the threads. Instead, the receiving thread has to send it to all the servers (while the other threads are still waiting to read from these servers).
In other words: break up the strict assignment of servers to threads. Let any thread send to any server.
Add each thread to a collection, say list and watch for the updates. As soon as an update is available, dispatch that to each thread. (Sounds like an observer...) !
The simplest solution is to pass a common object to both threads. In this case it might just be a String
. For example:
String messagePasser;
Connect f = new Connect(irc.freenode.net, 6667, messagePasser);
Thread ft = new Thread(f);
ft.start();
Connect q = new Connect(irc.quakenet.org, 6667, messagePasser);
Thread qt = new Thread(q);
qt.start();
Your other example then becomes:
if (lineReader.substring(lineReader.indexOf(":"), lineReader.length()).equals("hello")){
messagePasser = "Hello, World!";
}
Each thread then should constantly check messagePasser
to see when it changes and then output the message. This is obviously a very simple suggestion and completely bypasses many concerns about synchronization and thread safety.
EDIT: In light of learning that String
s are passed by value (learn something new every day...), You would merely have to create a simple MessagePasser
object that encapsulates a String
and any other data you would want.
精彩评论