Java: how to compare object in different threads - java

I have a server listening data from clients. Once a client sends data, it will go into a thread. Thus, each thread has a data. revFeaturePoints is the data which the server receives from clients.
Each revFeaturePoints has a float array, I want to compute the Euclidean distance between different revFeaturePoints in different thread?
I do not know how can let one thread to access another revFeaturePoints in other threads?
Here is the code:
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;
//bind a serverSocket to the port and listen
try{
serverSocket = new ServerSocket(8888);
System.out.println("Listening: 8888");
}catch(IOException e){
e.printStackTrace();
}
while(true)
new MyServerThread(serverSocket.accept()).start();
}
}
public class MyServerThread extends Thread{
//Create a socket for each client
private Socket socket = null;
private ObjectInputStream dataInputStream = null;
private ObjectOutputStream dataOutputStream = null;
private ArrayList<FeaturePointList> revFeaturePoints = null;
//constructor
public MyServerThread(Socket socket){
super("MyServerThread");
this.socket = socket;
}
#SuppressWarnings("unchecked")
public void run(){
try{
dataOutputStream = new ObjectOutputStream(socket.getOutputStream());
dataInputStream = new ObjectInputStream(socket.getInputStream());
System.out.println("ip: "+ socket.getInetAddress());
revFeaturePoints = (ArrayList<FeaturePointList>) dataInputStream.readObject();
}catch(IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(socket!=null){
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataInputStream!=null){
try{
dataInputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataOutputStream!=null){
try{
dataOutputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}

A simple way would be putting a synchronized method in MyServerThread that returns the data.
Another way of doing it would be to use a BlockingQueue and place the data result in a queue and taking the results from this as a producer-consumer pattern. See here for a way of doing this.

If your MyServerThread class stashes the data into a field, you can access that field from multiple instances of MyServerThread.

You can share the data among threads by using a shared structure and correct synchronization. For example, you could have a ConcurrentHashMap<'threadname', data> in MyServerThread where each thread puts its data and search for data in other threads.
That said, you should evaluate your architecture. If N threads have to check what the other N-1 threads are doing with data, you are preparing a recipe for performance disaster. Probably, what you would like to do is to create some layering in your architecture, where a number of ServerThreads are gathering the request and placing them in a concurrent shared structure (e.g queues). Then another set of workers are comparing and processing the data and producing results in a collaborative system. Have a look at the producer-consumer pattern.

[really a comment but won't fit ;)]
maasg's answer is quite correct in the general sense, but I believe you are right now looking at design difficulties and not Java threaded implementation per se.
You server (as is) fires off a disposable thread on each connect request, and this thread simply reads one object from the client and then closes the connection. The passed object is put in a (server thread) instance scoped object (which is duly garbage collected after you exit run()).
It is completely unclear -- and thus the impression that this is a design problem -- how you determine which 2 threads to compare, or for that matter, what guarantees you have that there will be (always) 2 concurrent threads to begin with.
Logically, you clearly have some domain specific association between a server thread and some meaningful matter in your domain. This relationship needs to be embodied in code, but first we need to understand what is this distinction and relationship.

Objects aren't 'in different threads'. Objects are members of other different objects, usually referenced via 'get' methods. Forget about the thread issue entirely, it is irrelevant. You just want to compare a member of object A with a member of object B. This is just business as usual.

Related

ArrayList empty when accessed from separate thread although it is populated.

I have a simple Client/Server Application. I try to access the arraylist from UI but get an empty arraylist in return. I have tried every possible solution on internet but none has worked in my case.
Server.java
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public class Server {
public static ArrayList<MyThread> clients = new ArrayList<MyThread>();
public static void main(String args[]) throws IOException {
ServerSocket s = new ServerSocket(7777);
try {
while (true) {
Socket s1 = s.accept();
MyThread t = new MyThread(s1);
clients.add(t); // adds threads to an ArrayList
System.out.println(clients); // prints the ArrayList(It works and print all threads)
t.start(); //start the thread
}
} catch (SocketException e) {
System.out.println("Error: " + e);
}
}
}
This is a MouseClickeed method in my UI class where I want to access the ArrayList in Server Class
public void mouseClicked(MouseEvent arg0) {
try {
String s = textField.getText();
Client.ClientName = s; \\ gets the string entered and set it as Client Name
System.out.println(Server.clients); \\It's supposed to print Client ArrayList but instead it prints an empty List ([])
}
catch (NullPointerException e1) {
System.out.println("Error: " + e1);
}
}
});
It's look like you try to use objects from Server application in client application with UI.
Server and client app are two different processes.
Server.clients is initialized with values in your server app, and isn't initialized in your client app.
You're not just working with separate threads, you're working with different processes.
The Server process has it's own Server.class instance. The Client is launched in a different java process, it could use the same classes, but they will be different instances, even the static fields will be different in different processes.
If you need data from the Server in the Client, you need some sort of communication. You already have tcp/ip socket, so you could send the list via the socket.
Or you could use some distributed cache library if you want to use this pattern in a large application. E.g. hazelcast or Terracotta DSO

Can I use PipedStreams to send Data from one Thread to multiple others?

I am programming a multi-threaded server and I have a thread for every client-socket-connection.
I want to pass data from the main thread back and forth to the client-threads.
How many threads do I have to set up?
Does it work like this:
[Server Class:]
private PipedInputStream serverInputStream = new PipedInputStream();
private PipedOutputStream serverOutputStream = new PipedOutputStream();
public PipedInputStream clientInputStream = new PipedInputStream();
public PipedOutputStream clientOutputStream = new PipedOutputStream();
serverInputStream.connect(clientOutputStream);
clientInputStream.connect(serverOutputStream);
or do I have to set up a these four of Streams for each client?
I apologize if this question is maybe dumb, but I have seen that as a possebility and tried it.
If there is a much better way to handle communication between threads then please educate me!
I have written a small Class that waits for a Buffered Reader that blocks and add the messages to the queue:
public class DataListener implements Runnable {
private InputStream is;
private ConcurrentLinkedQueue<String> messages;
private boolean closed = false;
public DataListener(InputStream is, ConcurrentLinkedQueue<String> messages) {
this.is = is;
this.messages = messages;
}
#Override
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while (!closed) {
try {
messages.add(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void close() {
closed = true;
}
}
Can you tell me if that is a good way of working around a blocking listener?
It is definitely not a good idea to use streams to pass data from one thread to another, because:
Stream IO are blocking operations, which would put the thread on hold.
Streams (in general) are not thread-safe by default, which could lead to all kinds of issues.
If you want to pass data between threads frequently try to avoid blocking at all cost, because otherwise the server thread will be waiting most of the time. Java offers a wide tool-set of non-blocking data exchange functionality that you can use instead, which you can find in the Concurrent Package.
A very simple yet effective and fast way to exchange data is to use a message-style system:
final ConcurrentLinkedQueue<MyMessageClass> messages = new ConcurrentLinkedQueue<MyMessageClass>();
public void addMessage(final MyMessageClass message) {
messaged.add(message);
}
protected void serverLoop() {
//...
final MyMessageClass message = messages.poll(); // does not block, returns null if none is available
if (message != null) {
handleMessage(message);
}
//...
}
You can use other classes like the LinkedBlockingQueue for additional features like temporary blocking.
However: when it comes to threading most problems can only be solved by using the correct architecture for your problem at hand. There is no "golden hammer" solution for all your threading tasks, if you want your code to run flawlessly, you need to find the appropriate solution.
You can only use any given piped steam pair between two threads. You will need a pair of pioed streams per thread pair. Don't do this. Use a queue.

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 do I design a program that does completely different tasks concurrently?

I've just got my feet wet with multi-threading and its really awesome. I find myself trying to figure out new ways I can use it make things better and I think I found one but I'm unsure how to design the program for this.
Here's the situation. I have a queue server that multiple clients consume and produce data to but to kick start the process I run a java program on to put some initial data for them to start. then my program is done and I have excess capacity on the queue server but nothing is really running on it. So I want to try to do some maintenance tasks, run a service, and do low priority stuff.I'm not sure how do that though. How do I design a program that does completely different tasks concurrently?
Typically I just wrap my programs in a while (true) loop and it does a single task and I realize I cannot do two while loops at the same time in the same process(maybe nested?). To show a simplified example, I put a bunch of code that runs a runnable(maybe it'll process a low priority queue) and a service that monitors a socket and replies back(I might want to add more depending on cpu usage). How do I get them all to work together? Is there a better way to design it(I know long term its probably better to run multiple java processes but right now I am just trying to manage a single file and I suspect there's a way to give the socket service a higher priority than processing the queue within the file but if they are both running in different files I don't know how to lower one over the other instead of them fighting for resources)?
Thanks and I'll edit this question if it turns out I'm explaining this totally wrong. But in a nutshell, I want it to provide a service to other systems(server socket, in the example) and when its idle I want it to do a few other tasks.
Example(if you understand what I'm asking this code may not be necessary to read):
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class multipleThreads {
private ServerSocket server;
private int port = 7777;
public void ServerSocketExample() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("starting");
ServerSocketExample example = new ServerSocketExample();
example.handleConnection();
while (true) {
//monitor low low priority queue
}
}
public void handleConnection() {
System.out.println("Waiting for client message...");
//
// The server do a loop here to accept all connection initiated by the
// client application.
//
while (true) {
try {
Socket socket = server.accept();
new ConnectionHandler(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable {
private Socket socket;
public ConnectionHandler(Socket socket) {
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run() {
try
{
//
// Read a message sent by client application
//
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message Received: " + message);
//
// Send a response information to the client application
//
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi...");
ois.close();
oos.close();
socket.close();
System.out.println("Waiting for client message...");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class MonitorQueue implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
//do work when stuff comes in the queue
}
}
I strongly recommend you take a look at this project: Java Concurrent Animated. I found this probably the best way to get my head around concurrency concepts in Java: it's animated, interactive, and you can just take one concept at a time and get a good understanding.
http://sourceforge.net/projects/javaconcurrenta/
Take a look at the java.util.concurrent package. It's full off goodies for doing exactly the kinds of things you describe.
In particular, check out the Executors factory class which lets you build Thread Pools that allow multiple tasks to be scheduled and run concurrently on any number of Threads you specify.
Oracle has some great tutorials on using Executors:
http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html
Concurrency is hard, you can read Java Concurrency in Practice, but even the experts have difficulties.
Look for a training course in your area.
I would like to recommend Concurrency Specialist Courses which is based on Java Concurrency in Practice and endorsed by the author, Brian Goetz

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

Categories