Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java share data between thread

i have a java process that reads data from a socket server. Thus i have a BufferedReader and a PrintWriter object corresponding to that socket.

Now in the same java process i have a multithreaded java server that accepts client connections. I want to achieve a functionality where all these clients that i accept can read data from the BufferedReader object that i mentioned above.(so that they can multiplex the data)

How do i make these individual client threads read the data from BuffereReader single object? Sorry for the confusion.

like image 665
ayush Avatar asked Feb 25 '23 22:02

ayush


2 Answers

I would strongly suggest that they don't access the BufferedReader directly. Assuming you know the format of the data, and that each client is trying to read the same format (if that's not the case, I can't see how it could work at all) I would suggest creating one thread to read from the BufferedReader and put work items in a Queue. There are lots of example of using producer/consumer queues in Java, and this is also likely to make it easier to test the client code.

Having only one thread accessing the BufferedReader means you don't need to worry about defining an atomic operation that all other threads will have to content for - your reading thread effectively defines that operation by deciding to add a work item to the queue.

EDIT: If all the clients should see all of the data, that reinforces my suggestion of having a single reader even further - except instead of having a Queue of data which items are removed from, you'd have a collection which clients can read all the existing data from. You'll need to use an appropriately thread-safe collection, but there are plenty of those in Java.

EDIT: Having just read your comment which says that each client should just see the last item read from the reader, that makes it even easier. Have one thread reading the data, but just keep a single variable with a reference to "the last item read". You probably either want to synchronize access to it or use an AtomicReference, but both of those are easy.

like image 147
Jon Skeet Avatar answered Mar 07 '23 16:03

Jon Skeet


The easiest thing is probably to create a temporary file and use java.nio.channels.FileChannel. The reason is that this already provides the reader/writer semantics you want. An alternative is to re-implement these semantics yourself with an in-memory scheme.

What you would do is read from your reader and append to the end of the file. Then your readers would get file channels initially pointing to the end of the file. You'll have to be careful to make sure they don't think they have reached end of stream when you are simply waiting on more input from the reader. You can either make downstream logic aware of this or provide some kind of wrapper around the readers.

Edit: this was written with the understanding that you want all readers to see everything. This is too complicated if that's not in fact what you want.

like image 30
rlibby Avatar answered Mar 07 '23 18:03

rlibby