If I have multiple Java threads writing to the same Socket instance simultaneously, will that affect the integrity of the objects that are read from the same socket? I.e., whether the contents of the objects will be messed up etc. It's fine for the ordering of objects to be random.
In general, there are no guarantees. Bits of different objects could well end up getting interleaved on the wire, rendering the result indecipherable. Therefore, you need to provide external synchronization.
It is interesting to note that even a single socket write at the OS level is not necessarily atomic. For further discussion, see Is it safe to issue blocking write() calls on the same TCP socket from multiple threads? and Be careful with the sendmsg() family of functions.
If I have multiple Java threads writing to the same Socket instance
simultaneously
You will be writing to the same OutputStream from multiple threads.
What makes you think that it is a good idea without synchronization? If you started writing to a file from multiple threads simultaneously without synchronization would you expect the file to contain anything meaningfull?
Related
I have some threads which are writing on the same MulticastSocket (depending by the scheduling, probably can happen than more then one thread is writing on the MulticastSocket at the same time). Do I have to get them write on it one per timer by using some form of locking, or the UDP protocol is doing this implicitly?
It doesn't really have anything to do with UDP. The documentation for MulticastSocket doesn't say it's threadsafe, so you can't assume it's threadsafe. You can't know that it doesn't update internal structures (such as an outbound buffer) which could be damaged by simultaneous access.
If all the threads are using the same instance of MulticastSaocket, you'll want to ensure they don't simultaneously call its methods. You can do that easily enough by synchronizing on the instance:
synchronized (theSocket) {
theSocket.send(/*...*/);
}
I have on input stream coming in that is periodically receiving data. One of my threads (let's call it threadA) reads every message from the stream and makes sure the data is ok, but will through an error otherwise. My other thread (let's call it threadB) needs to read a few specific messages and then process it. As of now I have threadA just store the important messages in a global variable, and threadB read the messages from the global variable.
Is there any way to allow for two threads to read from the same source to avoid this?
edit: the data coming in are responses to commands threadB issued. My issue is that threadB needs the replies from certain commands, which are issued in no particular pattern, but it does not need all the replies.
You probably could create a threadsafe inputstream or a wrapper and if the stream supports mark/reset you could also have two streams read the data in parallel. However, you'd have to handle situations where one thread reads faster than the other thus making mark/reset unusable or having to skip data - there's so much involved, I doubt you'll want to bother with all this.
I'd suggest you keep your basic setup but try to get rid of global variables, e.g. by using the obverser pattern, passing references to the shared store to the threads etc.
I'm coding a Java socket server that connects to Arduino which in turn send and receive data. As shown by the Java socket documentation I've set up the server to open a new thread for every connection.
My question is, how will I be able to send the data from the socket threads to my main thread? The socket will be constantly open, so the data has to be sent while the thread is running.
Any suggestion?
Update: the goal of the server is to send commands to an Arduino (ie. Turn ligh on or off) and receive data from sensors, therefore I need a way to obtain that data from the sensors which are connected to individual threads and to send them into a single one.
Sharing data among threads is always tricky. There is no "correct" answer, it all depends on your use case. I suppose you are not searching for the highest performance, but for easiness of use, right?
For that case, I would recommend looking at synchronized collections, maps, lists or queues perhaps. One class, which seems like a good fit for you, is ConcurrentLinkedQueue.
You can also create synchronized proxies for all usual collections using the factory methods in Collections class:
Collections.synchronizedList(new ArrayList<String>());
You do not have to synchronize access to them.
Another option, which might be an overkill, is using database. There are some in-memory databases, like H2.
In any case, I suggest you to lower the amount of shared information to the lowest possible level. For example, you can keep the "raw" data separate per thread (e.g. in ThreadLocal variables) and then just synchronize during aggregation.
You seem to have the right idea - you need a thread to run the connection to the external device and you need a main thread to run your application.
How do you share data between these threads: This isn't in general a problem - different threads can write to the same memory; within the same application threads share memory space.
What you probably want to avoid is the two thread concurrently changing or reading the data - java provides a very useful keyword - synchronized - to handle this sort of situation which is straight forward to use and provides the kind of guarantees you need. This is a bit technical but discusses the concurrency features.
Here is a tutorial you might be able to get some more information on. Please note, a quick google search will bring up lots of answers to your question.
http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html
In answer to your question, you can send the information from one thread to another by using a number of options - I would recommend if it is a simple setup, just use static variables/methods to pass the information.
Also as reference, for large scale programs, it is not recommended to start a thread for every connection. It works fine on smaller scale (e.g. a few number of clients), but scales poorly.
If this is a web application and you are just going to show the current readout of any of the sensors, then blocking queue is a huge overkill and will cause more problems than it solves. Just use a volatile static field of the required type. The field itself can be static, or it could reside in a singleton object, or it could be part of a context passed to the worker.
in the SharedState class:
static volatile float temperature;
in the thread:
SharedState.temperature = 13.2f;
In the web interface (assuming jsp):
<%= SharedState.temperature %>
btw: if you want to access last 10 readouts, then it's equally easy: just store an array with last 10 readouts instead of a single value (just don't modifiy what's inside the array, replace the whole array instead - otherwise synchronization issues might occur).
i have a problem when i write a program on android for monitoring ecg real time.
Ecg data is transfered to mobile in real time by udp. In mobile, there have 2 thread: a thread gets ecg data transfered, a thread draws the ecg data.
Cicurlar buffer is common data for two thread above, and two threads always confict when read and write to buffer. And result is that ecg is lost or slow.
Before user cicurlar buffer, i had used 5 linkedblockingqueu but result was same.
Can any one give me some solution for data for multithread in my program?
Thank you.
Sorry, my english is not good.!
there is model when i used linkedblockingqueue:
You need to synchronize access to your data using a shared lock. I highly recommend Java Concurrency in Practice if you want to truly understand threading and concurrency models in Java.
I think, Synchronization is the solution for your problem.
Threads communicate primarily by
sharing access to fields and the
objects reference fields refer to.
This form of communication is
extremely efficient, but makes two
kinds of errors possible: thread
interference and memory consistency
errors. The tool needed to prevent
these errors is synchronization.
From the JavaDoc's BlockingQueue
BlockingQueue implementations are
thread-safe. All queuing methods
achieve their effects atomically using
internal locks or other forms of
concurrency control. However, the bulk
Collection operations addAll,
containsAll, retainAll and removeAll
are not necessarily performed
atomically unless specified otherwise
in an implementation. So it is
possible, for example, for addAll(c)
to fail (throwing an exception) after
adding only some of the elements in c.
In my assumption you are directly accessing the collection (Any Fifo based), you must try to make a bean which should have getter and setters for data not for collection and the collection should be define in bean. you can create the bean object before you create thread objects and pass the bean object to threads at contructing time, hope this will you.
Is it possible to have one thread write to the OutputStream of a Java Socket, while another reads from the socket's InputStream, without the threads having to synchronize on the socket?
Sure. The exact situation you're describing shouldn't be a problem (reading and writing simultaneously).
Generally, the reading thread will block if there's nothing to read, and might timeout on the read operation if you've got a timeout specified.
Since the input stream and the output stream are separate objects within the Socket, the only thing you might concern yourself with is, what happens if you had 2 threads trying to read or write (two threads, same input/output stream) at the same time? The read/write methods of the InputStream/OutputStream classes are not synchronized. It is possible, however, that if you're using a sub-class of InputStream/OutputStream, that the reading/writing methods you're calling are synchronized. You can check the javadoc for whatever class/methods you're calling, and find that out pretty quick.
Yes, that's safe.
If you wanted more than one thread reading from the InputStream you would have to be more careful (assuming you are reading more than one byte at a time).