I have a server that receives various xml messages from clients (one thread per client) and routes the messages to different functions depending on the message type. Eg. if the first element in the messages contains the string 'login' it signifies that this is a login message so route the message to the login() function.
Anyway, I want to make this message so things don't get messed up if multiple clients are connected and the dispatcher switches threads in middle of the message routing. So here is how I am routing the messages -
public void processMessagesFromClient(Client client)
{
Document message;
while (true)
{
try
{
message = client.inputStream.readObject();
/*
* Determine the message type
*/
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType)
{
case LOGIN:
userModel.handleLogin();
...
...
...
etc...
}
} catch(Exception e) {}
}
So how can I make this thread safe? I figure I need to put a synchronise statement in somewhere but Im not sure where. Also Ive been reading around on the subject and I found this post which says there is an issue with using synchronise on 'this' -
https://stackoverflow.com/a/416198/1088617
And another post here which says singletons aren't suitable for using synchronise on (My class in the code above is a singleton) - https://stackoverflow.com/a/416202/1088617
Your class is already thread safe, because you are only using local variables.
Thread safety only comes into play when you access class state (ie fields), which your code doesn't (seem to) do.
What you are talking about is serialization - you want to funnel all message processing through one point to guarantee that message processing is one-at-a-time (starts and finishes atomically). The solution is simple: Employ a static synchronized method:
public void processMessagesFromClient(Client client) {
Document Message;
while (true) {
processMessage(client);
}
}
private static synchronized processMessage(Client client) {
try {
message = client.inputStream.readObject();
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType) {
case LOGIN:
userModel.handleLogin();
...
etc...
}
} catch(Exception e) {}
}
FYI static synchronized methods use the Class object as the lock. This code will make your code behave like a single thread, which your question seems to want.
I would actually have a message handler thread which is responsible for reading incoming messages. This will then hand off processing to a worker thread to do the time consuming processing of the message. You can use the Java ThreadPoolExecutor to manage this.
If you already have 1 thread per connection, then the only thing that you have to synchronize are the functions which handle the events (i.e. functions like userModel.handleLogin()).
I guess the best solution should be to use a thread safe queue like the ConcurrentQueue and use a single working thread to pick up this values and run the actions one by one.
Provided you have one of these objects per thread, you don't have a problem. You only need to synchronized a shared object which can be modified by one of the threads.
public void processMessagesFromClient(Client client) {
while (true) {
processMessage(client);
}
}
private void processMessage(Client client) {
try {
Document message = client.inputStream.readObject();
String messageType = getMessageType(message);
// Route the message depending on its type
switch (messageType) {
case LOGIN:
userModel.handleLogin();
...
etc...
}
} catch(Exception e) {}
}
You need to know which resource should be only used be one thread at a certain time.
In your case it is likely that reading the next message needs to protected.
synchronize (lock) {
message = client.inputStream.readObject();
}
However, your code sample does not really show what needs to protected against concurrent access
The method itself is thread safe.
However, noting that this your class is a singleton, you might want to use double checked locking in your getInstance to ensure thread safety.
Also you should make sure your instance is set to static
class Foo {
private static volatile Foo instance = null;
public static Foo getInstance() {
if (instance == null)
{
synchronized(this)
{
if (instance == null)
instance = new Foo ();
}
}
return instance ;
}
}
Related
I’ve been thinking about the simplest possible (and thus fastest) way to pass a message between two processes. So we have a producer thread and a consumer thread and they both hold a reference to the message passer. My current thinking for how this could work (where producer blocks until consumer has picked up the last message¹) is:²
class MessagePasser<T> {
enum MessagePasserState { SENT, RECEIVED }
private MessagePasserState state = RECEIVED;
private T message;
public void send(T message) {
while (state == SENT) {
Thread.sleep(50);
}
this.message = message;
state = SENT;
}
public T receive() {
while (state == RECEIVED) {
Thread.sleep(50);
}
T message = this.message;
state = SENT;
return message;
}
}
This obviously doesn’t work if more than one thread is accessing send() or receive() (is there any way to enforce that?³) but are there any other flaws in this approach?
I’m thinking that if this works, adding buffering should be simple.
Apologies for any typos, errors in the code: I’m writing this in the browser.
I wonder how this would work in other languages as well—e.g., C, C++, Rust, etc. I imagine this approach would be impossible in Rust, but there might be a way to pass ownership of the message holder between threads that would be neater.
I need to be able to 'send' a string from one thread to 1 or more other threads. But I have no idea how to do this.
Basically, I have a server who has one connection that sends commands to it. I need to send these commands to all the other threads, so they can send them to their clients.
How can I have a single string that is referenced by all the other threads. How to know when all the threads executed the command string?
Somewhere you will need a List of your Runnabless like:
List<MyRunnable> runningThreads;
Then you will have an implementation of Runnable:
class MyRunnable implements Runnable {
public void run() { ... }
}
Now you need to have some way of sending a message to that Runnable.
class MyRunnable implements Runnable {
public void run() { ... }
public void sendMessage( String message ){ ... }
}
So to send all the runnable a message it's as easy as:
for( MyRunnable runnable : runningThreads ){
sendMessage( "Hello There!" );
}
What to do now depends heavily on what you want to do next with the message. In any way it has to appear somehow in the Thread's visible range. So for starters lets save it in a variable:
class MyRunnable implements Runnable {
private volatile String myLastMessage;
public void run() { ... }
public void sendMessage( String message ){
this.myLastMessage = message;
}
so if you're run is already run periodically you can get off with:
public void run(){
while( true ){
Thread.sleep( 1000 ); //1s
if( lastMessage != null ){
doSomethingWith( lastMessage );
lastMessage = null;
}
}
}
If you need more than one message stored in the Thread you can use e.g. SynchronizedList for this.
If you need your Thread to react instantly on the message it received then use a monitor and
notifyAll method. See e.g. here: http://www.programcreek.com/2009/02/notify-and-wait-example/
If I understand you right, this is your setup:
How can I have a single string that is referenced by all the other threads?
When the string is sent via sockets or similar, it will be a different string. But with the same content, and that's what counts here. So I would not care too much about this point.
How to know when all the threads executed the command string?
Have each thread sent back a confirmation to the server whenever the thread finished processing a command for all clients. The server keeps track of all commands sent and confirmations received.
Keep in mind, that threads may crash, connections may break and the execution of a command may not succeed in a timely fashion, or fail entirely.
Perhaps you are refering to the Observer pattern (aka, Publish–subscribe pattern). The server (publisher) needs to know their clients (subscribers) in order to send a common message, so you need a data structure. There are several ways to implement this. See the next links:
Observer pattern with threads
The concurrent implementation of a publisher/subscriber pattern
Chaining of observer/observable pattern
I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
Another thread has following:
public void run(){
a.myCard = new Card(5);
}
What do you suggest?
You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card. Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.
The variable needs to be volatile when modifying from a different thread if you intend to poll for it, but a better solution is to use wait()/notify() or even a Semaphore to keep your other thread sleeping until myCard variable is initialized.
Looks like you have a classic producer/consumer case.
You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?
Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/
I have class Server and subclass ClientThread. ClientThread has methods receive() and broadcast(String[] msg) used to receive and send messages from/to clients connected to server.
Scheme:
public class Server extends Thread {
private ArrayList<ClientThread> clientThreads;
class ClientThread extends Thread {
public void broadcast(String[] msg) {...}
public void receive() {
...
if (msg.equals("CHANGED")) {
resumeOthers();
}
public void suspendOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
try {
c.wait();
} catch (InterruptedException e) {}
}
public void resumeOthers() {
for (ClientThread c: clientThreads)
if (c!=this)
c.notify();
}
}
public void run() {
...
cmd = new String[1];
cmd[0] = "PROMPTCHANGE";
for (ClientThread currPlayer: clientThreads) {
currPlayer.broadcast(cmd);
currPlayer.suspendOthers();
}
}
}
Now, I would like to make this ClientThreads work one after another, like this:
1. ClientThread number 1 is calling method broadcast.
Now any other ClientThread existing is freezed
(they are stored in ArrayList on Server)
2. Client (another class) replies with a message that is being caught by receive()
Now this thread is freezed, and the next one starts running
Unfortunately, my approach doesn't work.
Could somebody explain me in details how to achieve that?
by calling Object.wait(), you are are suspending the CALLING thread, not the thread that this object happens to be.
so in effect, you are doing a loop that blocks the calling thread N times, definitely not what you intended.
in order to pause a thread, you need to have IT wait on an objet, or have it block entering a synchronized block (or use Thread.sleep(), but usually its not a good solution).
in other words, the client threads need to call wait, not the calling thread.
One addition:
it seems you are new to Java threading and synchronization, I strongly suggest that you read about it before attempting this.
Google around for some docs on the subject.
here is something to get you started:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
It's not clear how the sequence of execution works.
Anyway, as already said by previous answers, calling x.wait() on a Object makes the current thread block on object x. Moreover, in order to call wait() and notify(), you first have to synchronize on that object, AND, when you call wait(), you should do it in a loop, checking for an external condition, because spurious wakeups can happen.
So, the correct pattern should be something like:
void waitForCondition() {
synchronized (lockObject) {
while (!condition) {
lockObject.wait();
}
}
}
void setCondition() {
synchronized (lockObject) {
condition = true;
lockObject.notify(); //or .notifyAll()
}
}
If you want to make the threads run one after another, try http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html
In most cases when you create your thread you can prepare the data beforehand and pass it into the constructor or method.
However in cases like an open socket connection you will typically already have a thread created but wish to tell it to perform some action.
Basic idea:
C#
private Thread _MyThread = new Thread(MyMethod);
this._MyThread.Start(param);
Java
private Thread _MyThread = new Thread(new MyRunnableClass(param));
this._MyThread.start();
Now what?
So what is the correct way to pass data to a running thread in C# and Java?
One way to pass data to a running thread is by implementing Message Queues. The thread that wants to tell the listening thread to do something would add an item to the queue of the listening thread. The listening thread reads from this thread in a blocking fashion. Causing it to wait when there are no actions to perform. Whenever another thread puts a message in the queue it will fetch the message, depending on the item and it's content you can then do something with it.
This is some Java / pseudo code:
class Listener
{
private Queue queue;
public SendMessage(Message m)
{
// This will be executed in the calling thread.
// The locking will be done either in this function or in the Add below
// depending on your Queue implementation.
synchronize(this.queue)
{
this.queue.put(m);
}
}
public Loop()
{
// This function should be called from the Listener thread.
while(true)
{
Message m = this.queue.take();
doAction(m);
}
}
public doAction(Message m)
{
if (m is StopMessage)
{
...
}
}
}
And the caller:
class Caller
{
private Listener listener;
LetItStop()
{
listener.SendMessage(new StopMessage());
}
}
Of course, there are a lot of best practices when programming paralllel/concurrent code. For example, instead of while(true) you should at the least add a field like run :: Bool that you can set to false when you receive a StopMessage. Depending on the language in which you want to implement this you will have other primitives and behaviour to deal with.
In Java for example you might want to use the java.util.Concurrent package to keep things simple for you.
Java
You could basically have a LinkedList (a LIFO) and proceed (with something) like this (untested) :
class MyRunnable<T> implements Runnable {
private LinkedList<T> queue;
private boolean stopped;
public MyRunnable(LinkedList<T> queue) {
this.queue = queue;
this.stopped = false;
}
public void stopRunning() {
stopped = true;
synchronized (queue) {
queue.notifyAll();
}
}
public void run() {
T current;
while (!stopped) {
synchronized (queue) {
queue.wait();
}
if (queue.isEmpty()) {
try { Thread.sleep(1); } catch (InterruptedException e) {}
} else {
current = queue.removeFirst();
// do something with the data from the queue
}
Thread.yield();
}
}
}
As you keep a reference to the instance of the LinkedList given in argument, somewhere else, all you have to do is :
synchronized (queue) {
queue.addLast(T); // add your T element here. You could even handle some
// sort of priority queue by adding at a given index
queue.notifyAll();
}
Edit: Misread question,
C#
What I normally do is create a Global Static Class and then set the values there. That way you can access it from both threads. Not sure if this is the preferred method and there could be cases where locking occurs (correct me if I'm wrong) which should be handled.
I haven't tried it but It should work for for the threadpool/backgroundworker as well.
One way I can think of is through property files.
Well, it depends a lot on the work that the thread is supposed to do.
For example, you can have a thread waiting for a Event (e.g. ManualResetEvent) and a shared queue where you put work items (can be data structures to be processed, or more clever commands following a Command pattern). Somebody adds new work to the queue ad signals the event, so the trhread awakes, gets work from the queue and start performing its task.
You can encapsulate this code inside a custom queue, where any thread that calls the Deque methods stops until somebody calls Add(item).
On the other hand, maybe you want to rely on .NET ThreadPool class to issue tasks to execute by the threads on the pool.
Does this example help a bit?
You can use delegate pattern where child threads subscribes to an event and main thread raises an event, passing the parameters.
You could run your worker thread within a loop (if that makes sense for your requirement) and check a flag on each execution of the loop. The flag would be set by the other thread to signal the worker thread that some state had changed, it could also set a field at the same time to pass the new state.
Additionally, you could use monitor.wait and monitor.pulse to signal the state changes between the threads.
Obviously, the above would need synchronization.