Java (Android) - Synchronized Queue and sending data - java

I've two threads. One for generating data, second for sending them to server. Is this a classic producer-consumer situation?
To do this I've constructed simple code for managing synchronised queue - I hope: I did it more or less correct? Could somebody answer me, please? My code is here below:
public ArrayList<String> Packets;
public synchronized void add_to_Queue (String data) {
Packets.add(data);
}
public synchronized void del_from_Queue (int position) {
Packets.remove(position);
}
public synchronized String read_from_ Queue(int position) {
return Packets.get(position);
}
public synchronized int number_of_element_of_Queue() {
return Packets.size();
}
First thread add new data by putting them using simple command:
add_to_Queue("XYZ);
Second one sending data in a loop:
while (OK)
{
try
{
while (number_of_element_of_Queue()>0)
{
out.write(read_from_Queue(0)+"\n");
out.flush;
del_from_Queue(0); // if no error delete just sent element
}
}
catch (IOException e1)
{
reconnect();
}
}
I think something is wrong because sending static data (simple static text instead of reading it from my "Queue") doesn't result in reconnection (i.e. after catch (IOException e1) ). But when I use presented code, it happens very often, especially after reconnection. It does it several times (send some data, reconnect, send some more data, again reconnect and so on).

Yeah, what happens if the queue is empty? You don't seem to be checking for that or handling it. But that is not the only condition you are not accounting for.
More generally, the implementation shown is not how a Queue works. Queues are first-in-first-out, no need for a position parameter. There is not a concept of "read" then "delete", those operations are usually atomic via a "take". You are best served by using an existing BlockingQueue implementation as opposed to writing your own.

Related

java multi threading - how to synchronise

I have a class with following method
public class Test {
private List l1;
public void send() {
for (<type> x : l1) {
//send to receivers and put a log in DB
}
}
}
This Test class is used by different threads which will fill the variable 'l1' with their own data and send them to receivers.
If I have to synchronize this to send data sequentially so that receivers get one full frame of data every time(without jumbling of data from different threads), should I synchronize on 'l1' or synchronize on the class Test.
I read the tutorials and samples but I still have this question.
You should synchronize on the object that represents you "shared state" (l1 in this case); you must ensure that every insert/read operation is synchronized
so you must have a synchronized(l1) {...} block for add (and remove) call and one while sending:
public void send() {
synchronized(l1) {
for (<type> x : l1) {
//send to receivers and put a log in DB
}
}
}
depending on you requirements you can also implement something more complex like:
public void send() {
synchronized(l1) {
List l2=new ArrayList(l1);
//clear l1?
}
for (<type> x : l2) {
//send to receivers and put a log in DB
}
}
and allow a grater degree of concurrency

Synchronize on DataOutputStream

I have gone through so many tutorials on Synchronization now that my head is spinning. I have never truly understood it :(.
I have a Java server(MainServer), that when a client connects creates a new thread(ServerThread) with a DataOutputStream.
The client talks to the ServerThread and the ServerThread responds. Every now and then the MainServer will distribute a message to all clients utilizing each ServerThread's DataOutputStream object.
I am quite certain that every now and then my issue is because both the MainServer and ServerThread are trying to send something to the client at the same time. Therefore I need to lock on the DataOutputStream object. For the life of me I cannot understand this concept any further. Every example I read is confusing.
What is the correct way to handle this?
ServerThread's send to client method:
public void replyToOne(String reply){
try {
commandOut.writeUTF(reply);
commandOut.flush();
} catch (IOException e) {
logger.fatal("replyToOne", e);
}
logger.info(reply);
}
MainServer's distribute to all clients method:
public static void distribute(String broadcastMessage){
for (Map.Entry<String, Object[]> entry : AccountInfoList.entrySet()) {
Object[] tmpObjArray = entry.getValue();
DataOutputStream temporaryCOut = (DataOutputStream) tmpObjArray[INT_COMMAND_OUT]; //can be grabbed while thread is using it
try {
temporaryCOut.writeUTF(broadcastMessage);
temporaryCOut.flush();
} catch (IOException e) {
logger.error("distribute: writeUTF", e);
}
logger.info(broadcastMessage);
}
}
I am thinking I should have something like this in my ServerThread class.
public synchronized DataOutputStream getCommandOut(){
return commandOut;
}
Is it really that simple? I know this has likely been asked and answered, but I don't seem to be getting it still, without individual help.
If this were me.....
I would have a LinkedBlockingQueue on each client-side thread. Then, each time the client thread has a moment of idleness on the socket, it checks the queue. If there's a message to send from the queue, it sends it.
Then, the server, if it needs to, can just add items to that queue, and, when the connection has some space, it will be sent.
Add the queue, have a method on the ServerThread something like:
addBroadcastMessage(MyData data) {
broadcastQueue.add(data);
}
and then, on the socket side, have a loop that has a timeout-block on it, so that it breaks out of the socket if it is idle, and then just:
while (!broadcastQueue.isEmpty()) {
MyData data = broadcastQueue.poll();
.... send the data....
}
and you're done.
The LinkedBlockingQueue will manage the locking and synchronization for you.
You are on the right track.
Every statement modifying the DataOutputStream should be synchronized on this DataOutputStream so that it is not concurrently accessed (and thus do not have any concurrent modification):
public void replyToOne(String reply){
try {
synchronized(commandOut) { // writing block
commandOut.writeUTF(reply);
commandOut.flush();
}
} catch (IOException e) {
logger.fatal("replyToOne", e);
}
logger.info(reply);
}
And:
public static void distribute(String broadcastMessage){
for (Map.Entry<String, Object[]> entry : AccountInfoList.entrySet()) {
Object[] tmpObjArray = entry.getValue();
DataOutputStream temporaryCOut = (DataOutputStream) tmpObjArray[INT_COMMAND_OUT]; //can be grabbed while thread is using it
try {
synchronized(temporaryCOut) { // writing block
temporaryCOut.writeUTF(broadcastMessage);
temporaryCOut.flush();
}
} catch (IOException e) {
logger.error("distribute: writeUTF", e);
}
logger.info(broadcastMessage);
}
}
Just putting my 2 cents:
The way I implement servers is this:
Each server is a thread with one task only: listening for connections. Once it recognizes a connection it generates a new thread to handle the connection's input/output (I call this sub-class ClientHandler).
The server also keeps a list of all connected clients.
ClientHandlers are responsible for user-server interactions. From here, things are pretty simple:
Disclaimer: there are no try-catches blocks here! add them yourself. Of course you can use thread executers to limit the number of concurrent connections.
Server's run() method:
#Override
public void run(){
isRunning = true;
while(isRunning){
ClientHandler ch = new ClientHandler(serversocket.accept());
clients.add(ch);
ch.start();
}
}
ClientHandler's ctor:
public ClientHandler(Socket client){
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
}
ClientHandler's run() method:
#Override
public void run(){
isConnected = true;
while(isConnected){
handle(in.readObject());
}
}
and handle() method:
private void handle(Object o){
//Your implementation
}
If you want a unified channel say for output then you'll have to synchronize it as instructed to avoid unexpected results.
There are 2 simple ways to do this:
Wrap every call to output in synchronized(this) block
Use a getter for output (like you did) with synchronized keyword.

How can I make this thread safe?

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 ;
}
}

What is the best way to manage text-based client-server connections?

I'm looking to write a small client-server-based text game that handles multiple client connections and persistently affects a game state. I'm wondering what the best way would be to handle multiple connects such that commands are processed in the order they arrive at the server.
Ideally I'm not looking to take advantage of multi-threading, at least on the command processing level. I would be okay with each client having a separate thread (in order to have blocking IO on each thread), as long as I could unify the processing in a single thread thereafter.
Since the only communication between the client and server will be text, I'm not sure how best to go about setting up the communication. If I chose blocking IO, how would I get queue the processing to occur in a single thread?
Alternatively, if I choose non-blocking IO and use a selector to query for when clients have written to the server, how can I get read a String of unknown/unlimited length without using a set-size ByteBuffer? Non-blocking also favours keeping the processing in a single thread as it can just read from the client connections as and when they send new data. However, when I tried to implement it with read/writeUTF I came up against the IllegalBlockingModeException heh.
Any answers to the questions or suggestions on how to do this in a way I haven't mentioned would be sincerely appreciated! I'm fairly new to clients and servers so I don't know whether java.io or java.nio would be most appropriate.
Sorry for the convoluted question. I think I ran away with myself.
Opinions differ, but I'd definitely go with a single thread per client. The communication to the single processing thread could then go via a LinkedBlockingQueue, or just a synchronized LinkedList.
Something like this on the per-client thread:
public class Client implements Runnable, ResponseOutput {
private final BufferedReader br;
private final PrintWriter pw;
public Client(Socket s) {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream());
}
// defined by the ResponseOutput interface
public void sendReply(String reply) {
pw.println(reply);
}
public void run() {
try {
while (true) {
String s = br.readLine();
if (s==null)
break;
Processor.queue(new Processor.InputItem(this, s));
}
} catch (IOException ioe) {
... error handling ...
}
}
}
Then this for the processing:
public class Processor implements Runnable {
static public class InputItem {
final ResponseOutput client;
final String command;
public InputItem(ResponseOutput client, String command) {
this.client = client;
this.command = command;
}
}
static private Processor instance;
static public void queue(InputItem item) {
instance.commandQueue.add(item);
}
private BlockingQueue<InputItem> commandQueue;
public void run() {
try {
while (true) {
InputItem item = commandQueue.take();
String reply = doStuff(item.command);
item.client.sendReply(reply);
}
} catch (InterruptedException ie) {
... error handling ....
}
}
}
Within the InputItem class, you can also include a reference to any game state that needs updating. Since there's only the processing thread changing it, you get to do that without any synchronization.
i'm no expert in sever client systems but I'll share a couple of tips
Depending on your need you could simply set up a Tomcat server and do http request, its fairly straight forwards and of course all in Java.
the downside is that the request might be a bit slow.
The Second option you can check out is RMI.
The concept is simple you connect to another computer and when that is done you call methods on the other computer from a local object in you code.
http://java.sun.com/developer/onlineTraining/rmi/RMI.html
it might look a bit complicated (and sometimes debbuging a stack through multiple computer is a bit tricky) but I recommend because it keeps your code clear.
Finally you can try sockets but there your on your own :P

What is the correct way to pass data to a running thread

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.

Categories