2009-08-13 20 views
0

Eclipse IDEの出力から実行するJavaプログラムが、Windows(XP)のコマンドラインで同じことをするのと異なる理由はありますか?私はJDK 1.6.0_04とEclipse 3.4.0を使用していますEclipseとコマンドラインのJava出力が異なる

プログラムはスレッドを作成し、ロックアルゴリズムをテストします。 Eclipseでは、スレッドは互いに干渉しません。ただし、javacを使用すると、スレッドは互いに干渉し合います。

+4

詳細情報を入力してください:どのように正確に「異なる」? –

+0

は、さまざまなJVM、スレッド出力、異なるログ設定、ログレベルに影響を与えるデバッグ –

答えて

2

異なる動作の原因になっている可能性のあるものは、あなたが持っている場合です。同じ機能を提供する2つのjar(つまり、同じjarの2つのバージョン)。クラスパスの指定方法によっては、一方のjarのコードが他方のjarを上書きすることができます。

今すぐ注文がコマンドラインと異なる場合があります。実際には別のコードを呼び出し、出力が異なります。

+0

Eclipseの生成されたクラスパス情報を保持する方法があるようです。 – pypmannetjies

2

あなたがスレッドで遊んでいるなら、コンソールの出力はマシンごとに大きく変わることがあります。そして、私は日食が何らかの方法でスレッディングに影響すると確信しています。

1

Eclipseには独自のコンパイラが組み込まれているという印象を受けました(Google検索で正しいと私は確信しています)。 javacとのコンパイル方法に若干の違いがあるかもしれません。

0

はい、おそらくEclipseで冗長ガベージコレクションなどのJAVAオプションが有効になっている可能性があります。通常、[jre] /bin/Jconsole.exeを使用してJVMに接続し、JVMで有効になっているものを確認してから比較することができます。これにより、クラスパスの違いだけでなく、他のものも表示されます。 -Dcom.sun.management.jmxremote

0


はあなたが必要な場合には、適切にスレッドを同期してもよろしいです:あなたが点検したいJVMの起動オプションとしてこれを追加する必要があり、その作業を行うには?

スレッドは互いに依存していますか?そうであれば、これは行動の違いの可能性が高い理由です。

あなたのプログラムを分析してみてください。スレッド1がスレッド2より速く終了する場合、プログラムは動作しますか?スレッド2がスレッド1より速く完了すればプログラムは動作しますか?

たとえば、スレッド1が結果を生成し、後でスレッド2によって使用される場合、スレッド2が生成される前にその結果を使用しようとしないという保証はありますか?要約で

を(2つの実行本当に速いそのスレッドを言うことができます):異なる相対的な実行時間は、「プログラムがひどく

0

を同期している場合、私はあなたが言うことを前提とし、挙動の違いの理由かもしれませんスレッドが互いに割り込みします "2つのスレッドからの出力が混在していることを意味します。また、あなたがSystem.errまたはSystem.outに書き込んでいると思います。

私はあなたが見ているものは、2つのスレッドが同じストリームに非同期出力を行っていることが原因であると考えています。 Eclipseでは、write()の呼び出しがストールしないように十分なバッファリングを行います(99.9%)。対照的に、コマンドラインから実行すると、それぞれのJavaのwrite()呼び出しが1つのスレッドを停止し、もう1つをスケジューリングする書き込みシステムコールを引き起こす可能性があります。実際、Javaのwrite()が複数の書き込みシステムコールに変わる可能性もあります。

単純な答えは、ストリームのバッファリングを変更しようとすることです。残念なことに、私は、Java APIを使用して、コンソールの標準出力/エラーストリームに対してこれを行うことはできないと考えています。

他の不完全な答えは次のとおりです。

  • はのSystem.out/Errオブジェクト上のすべての書き込みを同期させるために、アプリケーションを変更し

    。残念ながら、これはテストしようとしているコードの同期バグを隠す恐れがあります!!

  • ByteArrayOutputStream()に出力するようにアプリケーションを変更します。これは「中断」の変化を減らしますが、あなたが同期しない限り、時々起こることがあります。

私は考えることができる最良の答えは、インスタンスへのすべてのメッセージを書き、ByteArrayOutputStreamに書き出し同期するラッパーストリーム/リーダークラスを作成することで、その後のSystem.out(または場所)に多くのことをダンプしますテストが完了したとき。これは同期のバグを隠す可能性がありますが、System.out/errオブジェクトで同期した場合よりもはるかに少なくなります。

関連する問題