17

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.

JRR
  • 6,014
  • 6
  • 39
  • 59
  • What does it write? Array, arraylist, hashtable? One of these is thread-safe. – huseyin tugrul buyukisik Nov 24 '12 at 21:05
  • @tuğrul: Which one of these is? Using the normal ObjectOutputStream (which I assume is what he's doing) doesn't give any guarantees. – Voo Nov 24 '12 at 21:09
  • @Voo: HashTable is thread-safe as i remember. http://stackoverflow.com/questions/7400292/is-java-util-hashtable-thread-safe – huseyin tugrul buyukisik Nov 24 '12 at 21:10
  • HashTable variables are thread-safe. Worths a try . http://stackoverflow.com/questions/7400292/is-java-util-hashtable-thread-safe – huseyin tugrul buyukisik Nov 24 '12 at 21:11
  • 4
    @tuğrul: There's a *big* difference between operations **on** the hashtable being thread safe and you being able to store more than one HashTable (or whatever) at the same time in a stream. The later is a property of the stream not the hashtable and what this question is about. – Voo Nov 24 '12 at 21:11
  • 2
    possible duplicate of [Thread safety of SocketOutputStream](http://stackoverflow.com/questions/10490391/thread-safety-of-socketoutputstream) – Marko Topolnik Nov 24 '12 at 21:18

2 Answers2

16

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.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Then how about multiple Socket instances that connect the same two machines? If the underlying OS calls are not thread-safe then it seems that multiple Socket instances would also not be thread-safe? – JRR Nov 24 '12 at 21:34
  • @JRR: I am afraid I don't follow your reasoning. To me it seems pretty clear that with careful coding multiple sockets can be made to work without application-level synchronization. – NPE Nov 24 '12 at 21:37
  • Thanks. I understand what you mean. I'm just asking if w/o any application-level synchronization whether the multiple socket instances multiple threads and the single socket instance multiple threads are the same in the sense that both are not thread-safe. – JRR Nov 24 '12 at 22:18
  • 1
    @JRR That question doesn't make sense. If you have a separate socket per thread the question of thread safety doesn't arise at all. There is nothing accessed by multiple threads so there is nothing to *be* thread-safe or otherwise. – user207421 Nov 24 '12 at 23:54
  • @EJP Well if the multiple Socket instances shares the same native socket without any locking mechanism then that would be a problem right? – JRR Nov 25 '12 at 00:08
  • @JRR Yes but that would obviously be a bug either in the OS or the JVM implementation. You can't just share two distinct instances of an object if that influences the behavior without quite explicitly stating such a severe limitation. Not really something the JVM would do anyhow and for the native tcp library the two sockets are distinct anyhow. – Voo Nov 26 '12 at 07:58
  • @NPE can you check http://stackoverflow.com/questions/29391196/multiple-threads-listening-to-single-socket This is related to this question – Kushal Apr 01 '15 at 12:46
  • @JRR But they don't share the same socket instance. Your point eludes me. – user207421 Jul 09 '16 at 18:11
5

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?

Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • Javadoc from SocketChannel.write() method: "This method may be invoked at any time. If another thread has already initiated a write operation upon this channel, however, then an invocation of this method will block until the first operation is complete." So using the SocketChannel for writing is thread safe. – Sam Goldberg Nov 20 '14 at 14:31
  • 1
    Yes and SocketChannel is good pointer to solve some people's needs but I just would like to point out that `SocketChannel` belongs to the NIO package which is separate from `java.net.Socket` which the question is about. For reference: http://stackoverflow.com/questions/14225957/socket-vs-socketchannel – Piovezan Sep 30 '15 at 15:07
  • @Piovezan The same is true of `Socket.` – user207421 Jul 09 '16 at 18:13
  • @EJP To be honest I can't find a SocketChannel implementation. I'm assuming it comes from the OS and that the write synchronization depends on the OS as well (despite what the documentation says the 2nd link in the accepted answer lists quite a few untrustworthy OS's). I did find this [SocketChannelImpl.write()](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/SocketChannelImpl.java#SocketChannelImpl.write%28java.nio.ByteBuffer%29) and it features a write lock but I'm not sure how they relate. Socket's OutputStream comes from the OS as well, doesn't it? – Piovezan Jul 09 '16 at 21:18
  • @EJP Actually I suck at searching through GrepCode. [SocketChannelImpl](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/SocketChannelImpl.java#SocketChannelImpl) is the implementation every SelectorProvider subclass provides. It doesn't come from the OS. So SocketChannel features a write lock, but I'm afraid Socket's [SocketOutputStream](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/net/SocketOutputStream.java#SocketOutputStream.write%28byte[]%29) does not and is dependent upon the OS' (lack of) atomicity. – Piovezan Jul 09 '16 at 21:44