2016-03-24 25 views
-1

このトピックに関するいくつかの質問があることがわかりましたが、それは数年前か非常に精巧ではありません。Java Non-Blocking IO ObjectStream

私は以前のアプリケーションをSocketの新しいNIO SocketChannelに移行していました。なぜなら、それは不安定な状態で動作していたため、もう一度(コードレビューの一環として)この作業を行うつもりだったからです。だから私は非ブロッキングSocketChannelを使用していて、ちょうどObjectInputStreamObjectOutputStreamを使うことができないことを知りました。 明らかに、SocketChannelには転送されるデータのサイズが必要です。

この問題の解決方法はありますか?おそらくテンプレートが使えるのでしょうか、またはベストプラクティスとして一般的に承認されているソリューションですか(パターン)?私がちょうどとObjectOutputStreamを利用できるという事実は、すべてをもっと簡単にしました。独自の実装を作成する必要がある場合、おそらくあまりにも多くの時間を必要とし、より安定させるためにアプリケーションで多くのことを壊すでしょう。要約で

質問:

  • 非ブロックSocketChannelObjectInputStreamObjectOutputStreamを使用するための一般的な解決策はありますか?
  • ノンブロッキングモードで着信接続を受け入れるようなハイブリッドを作ることもできます。セレクタが読み込むものがあると分かったら、それはブロッキングモードに変わりますか? (私はそれがひどいと思うけど、私はちょっと必死です。)

PS:Java 8を使用し、それはTCP-Streamです。

+1

NIOに移行することは、不安定性の問題を解決するものではありません。あなたはほとんど確実にそれを悪化させます。元の問題を解決して、新しいコードを書いてはいけません。 – EJP

+0

@EJPの移行は、不安定性の問題を解決するものではありませんでした。主にすべてをより効率的にすることです。 「古い」実装の部分をレビューすることに努力するのではなく、全体をより良くするために努力していました。とにかく遅かれ早かれNIOに移行しようとしていたので(それが計画でした)。 –

+1

あなたの質問は、私が言及したことを正確に言う:「不安定性の問題のため」。いずれにしても、NIOを使用することによるスピードアップのメリットはほとんどありません。オブジェクトストリームとの統合は非常に困難です。私はあなたがしないことをお勧めします。強く – EJP

答えて

2

私はNon-Blocking SocketChannelを使用していますが、ObjectInputStreamとObjectOutputStreamを使用できないことがわかりました。なぜなら、非ブロック化されているからです。

デフォルトでSocketChannelはブロックされています。ノンブロッキングを望まない場合は、そのように設定しないでください。

ObjectInputStreamとObjectOutputStreamは、単純なJava IOで使用する方がはるかに簡単です。

明らかに、SocketChannelには転送されるデータのサイズが必要です。

これは必須ではありませんが、オブジェクト*ストリームを使用している場合は簡単です。

この問題の解決方法はありますか?

パートは、プレーンIOを使用しているか、NIOを使用する前にある長さのデータブロックを使用しています。

パフォーマンスを向上させたい場合は、別のシリアル化ライブラリを使用することをお勧めします。組み込みのものは最も遅いオプションの1つです。

多くのテンプレートが使用できますか、またはベストプラクティス(パターン)として一般に承認されている解決策がありますか?

プレーンIOと高速シリアライザの使用。

私がObjectInputStreamとObjectOutputStreamを利用できるという事実は、すべてをもっと簡単にしました。

NIOを使用したくない場合は、ノンブロッキングIOとセレクタを使用する場合には10倍の時間がかかります。

独自の実装を作成する必要がある場合、おそらくあまりにも多くの時間を必要とし、より安定させるためにアプリケーションで多くのことを行う必要があります。

選択肢が非常に多い場合は合意してください。

ノンブロッキングSocketChannelでObjectInputStreamおよびObjectOutputStreamを使用する一般的なソリューションはありますか?

全くありません。

私は多分非ブロックモードでの着信接続を受け入れるように、ハイブリッドを作り、セレクターが読むためのものがあることを発見したとき、それは、ブロッキング・モードに変更することはできますか? (私はそれがひどいと思うけど、私はちょっと必死です。)

確かに、私が言ったように、SocketChannelはデフォルトでブロックされているので、何もする必要はありません。私はアクセプタもブロックするようにします。

PS:Java 8を使用していて、それはTCP-Streamです。

Java 1.4を使用していても問題はありません。これらの図書館は過去12年間で劇的に変化していません。

+0

こんにちはピーター、すばやい返信をありがとう。私はあなたが類似の問題について誰かを助けた他の投稿を読んだ。問題は、NIOの主な利点は(私の意見では)ノンブロッキングを処理する必要がないということです。私は自分のアプリケーションをより効率的にするために努力しています.NIOは明らかなステップです。本当に解決策はありませんか? –

+0

@ElMac 'NIOの主な利点は、ノンブロッキングを処理する必要がないということです。意味がありません。ストリームでノンブロッキングを処理する必要はありません(できません)。あなたのプロジェクトは非常に動機が不十分で、理解が非常に悪いようです。 – EJP

+0

@EJP私はそれらを非ブロック(エンドユーザ向け)にしなければなりません。私はワーカースレッド上で実行することでこれを実現します。 –

0

ByteArrayOutputStreamをラップするObjectOutputStreamを使用してオブジェクトをシリアライズし、結果としてbyte[]バッファを取得します。バッファをSocketChannel経由で送信します。他端に

、あなたSocketChannelからbyte[]バッファを抽出し、ByteArrayInputStreamを構築し、そしてObjectInputStream、あなたのオブジェクトを読み出します。

+0

これは、シリアライズが単一のバッファに収まり、完全に受信された場合にのみ機能します。これを一般的なケースで動作させるには、長さの単語とシリアル化されたデータを送信する必要があります。これはワイヤプロトコルの変更であり、両方のピアを同時にアップグレードする必要があることを意味します。これは本当に哀れな人のためではありません。 – EJP

+0

@EJPはい、それはOPによって要求されるように、ハイブリッドアプローチです。 SocketChannelはノンブロッキングの仕方で動作します。完全なバッファを構築できるようになるまで、バッファフラグメントを蓄積します。次に、 'ObjectInputStream'は受信バッファ全体で動作するので、それがブロックしていることには関係ありません。部分的なバッファの累積は、バッファの長さをバッファの前に送ることを意味します。私はそれが大きなハードルであるとは思わない。アプリケーションが不安定であるため、このレイヤーの分割は、不安定性の発生場所を特定するのに役立ちます。 – AJNeufeld

+0

"完全なバッファを構築できるようになるまでバッファフラグメントを蓄積する*" - それはI/Oをブロックするための完全な記述です。ノンブロッキング・チャネルの上にブロックI/Oを再実装する点は何ですか? – Holger