10

BufferedReaders と BufferedWriters を介して、読み取りと書き込みの両方を行っている Socket があります。別のスレッドからどの操作を実行してもよいかわかりません。2 つの異なるスレッドから同時にソケットに書き込むのはよくないと思います。2 つの異なるスレッドから同時にソケットを読み取る場合と同じです。あるスレッドで読み取りながら別のスレッドで書き込みを行うのはどうですか?

より多くのデータを待機するため、読み取り時に1つのスレッドを長時間ブロックしたいのでお願いしますが、この待機中にソケットで送信するデータも時々あります。これがスレッドセーフなのか、それとも書き込みの前に読み取りをキャンセルする必要があるのか​​ どうかはわかりません(これは面倒です)。

4

6 に答える 6

6

ソケットは、ストリーム レベルでスレッド アンセーフです。同期を提供する必要があります。唯一の保証は、同時実行性に関係なく、異なる読み取り呼び出しでまったく同じバイトのコピーを取得しないことです。

しかし、リーダー レベル、特にライター レベルでは、ロックの問題が発生する可能性があります。

いずれにせよ、ソケットのストリームを使用した読み取りおよび書き込み操作は、完全に独立したオブジェクトであるかのように処理できます (それらが共有するのはライフサイクルだけです)。

一方のリーダー スレッドと他方のライター スレッドの間で正しい同期を提供すると、リーダーとライターの数に制限はありません。つまり、はい、あるスレッドで読み取り、別のスレッドで書き込みを行うことができ (実際、これは非常に頻繁に行われます)、書き込み中に読み取りを停止する必要はありません。

最後のアドバイス: スレッドに関連するすべての操作にはタイムアウトが関連付けられています。タイムアウトを正しく処理するようにしてください。

于 2011-07-12T23:58:34.843 に答える
5

実際に InputStream から読み取り、OutputStream に書き込みます。それらはかなり独立しており、それぞれへのアクセスをシリアル化する限り問題ありません。

ただし、送信するデータと受信するデータを関連付ける必要があります。それはスレッドセーフとは異なります。

于 2011-07-12T23:38:39.070 に答える
2

Javajava.net.Socketは実際にはスレッド セーフではありません。Socket ソースを開き、(たとえば) connectedmember フィールドとその使用方法を確認します。同期せずvolatileに読み取られ、更新されていないことがわかります。これは、Socket クラスが複数のスレッドで使用されるように設計されていないことを示しています。ただし、いくつかのロックと同期がありますが、一貫性がありません。

しないことをお勧めします。最終的には、buffers(nio) を使用し、1 つのスレッドでソケットの読み取り/書き込みを行います。

詳細については、ディスカッションvを参照してください。

于 2011-07-12T23:48:59.330 に答える
1

1 つのスレッドがソケットを読み取り、別のスレッドがソケットに書き込むことができます。多数のスレッドがソケットに書き込むようにしたい場合があります。その場合、同期を使用してアクセスをシリアル化するか、キューから書き込むデータを取得する単一の書き込みスレッドを持つことができます。(私は前者の方が好きです)

ノンブロッキング IO を使用して、読み取りと書き込みの作業を 1 つのスレッドで共有できます。ただし、これは実際にはより複雑で、正しく理解するのが難しいものです。これを行いたい場合は、Netty や Mina などのライブラリを使用することをお勧めします。

于 2011-07-13T07:58:58.207 に答える
0

非常に興味深いのは、nio SocketChannel の書き込みが同期されていることです。

http://www.docjar.com/html/api/sun/nio/ch/SocketChannelImpl.java.html

古いioソケットのものはOSに依存するため、OSのネイティブコードを確認して確認する必要があります(OSによって異なる場合があります)...

Socket.getOutputStream が返す java.net.SocketOutputStream.java を見てください。

(もちろん、私が何かを逃した場合を除きます)。

ああ、もう 1 つ、各 OS のすべての JVM のネイティブ コードに同期を組み込むこともできましたが、確かなことは誰にもわかりません。同期が存在することは明らかです。

于 2012-04-11T23:54:24.443 に答える