2009-08-17 16 views
4

Javaでスレッドが互いに分離されていることを確認する確実な方法はありますか?私は1週間半の間問題を抱えていました。ここでは、さまざまなサードパーティのソースコードを実装しているスレッドが、静的変数や実際は自分のコントロールを超えているために衝突し続けています。Javaでのスレッド分離

私が望むように、単一のシステムが、私が取り組んでいるプロジェクトの多くのインスタンスを実行できることは分かっています。しかし、スレッド化された単一の実行可能ファイルにすべてを組み込もうとすると、常にエラーと例外が発生します。

私が望むこのプログラムの各インスタンスについて、新しいプロセスを立ち上げるのはほぼまさにポイントですが、実際にはこのルートを降りてはいけません。集まって、ターゲットプロセスを殺す能力を妨げるだけでなく)。

提案はありますか?ありがとう!

答えて

9

使用したいライブラリの作成者がコードをスレッドセーフに設計していない場合は、2つのスレッドが同時に呼び出すのを防ぐために、あなたは簡単に行うことができます。

クラスローダーでいくつかのトリックを引き出すことはできますが、これはまったく新しい複雑さの世界につながります。具体的には、異なるクラスローダーを使用する場合は、同じクラスを同じJVMに2回(またはそれ以上)ロードすることが可能です。したがって、静的変数の独立したコピーを効果的に取得できます。別々のクラスローダーの使用は、一部のJava EEアプリケーションサーバーによって悪用されます。そのため、ライブラリ自体がリフレクションと動的クラスローディングを開始するときに、クラスローダとクラスパスがどのクラスに使用されるのかという疑問が生じます。あなたの必要性が非常に大きい場合を除いて、私はこのappraochをお勧めしません。

1)。安全でないコードに対しては、シングルスレッドワーカーを用意してください。できるだけ多くの作業をマルチスレッドのアプリケーションでやってみてください。できればできるだけ作業者に落としてください。

2)。作業者が処理の大部分を占めていて、実際に並列実行が必要な場合は、ワーカーを複数の別々のプロセスに分け、IPC通信を使用してワークアウトを共有します。これは、JMSキューイングのソリューションがうまく動作するように感じる。

3)。あなたがIPCの過熱を余裕がない場合は、ライブラリの代わりにスレッドセーフな代替手段を見つけようとするか、著者に影響を与えてコードを修正してください。彼らの並列性を高めることは本当に難しいことではありません。

0

残念ながら、これを行う方法はありません。スレッドが共有リソースにアクセスする場合、必要に応じてこれらのリソースをロックする必要があります。そうしないと、プログラムは共有状態の破損に直面します。

アクセスを同期させる方法で共有リソースへのアクセスをラップすることはできますか?

0

は、私はちょうど 私は、 をしたい、このプログラムの各 インスタンスのための新しいプロセスを起動した時点で、ほとんどが、私は本当にむしろこの ルートを下るないと思います(それは多くを排除します リアルタイムIが集まるデータだけでなく、 の目標 プロセスを殺すために自分の能力を妨げる。)それの音に

、あなたが再利用しようとしているコードは、実際に使用するように設計されていませんマルチスレッドアプリケーションで使用できます。この場合、インスタンスごとに別々のプロセスを起動することが実際には最適な選択肢になります。各インスタンスを削除する能力を妨げるのではなく、実際にこれを簡単にする必要があります。 Process.destroy()を参照してください。

"リアルタイム"が何を意味するのかはっきりしませんが、各子プロセスが標準出力に書き込む場合は、制御プログラムを記述して出力を読み込んで照合するようにコードすることができます。

4

さまざまなサードパーティのソースコードを実装するスレッドは、静的な変数や実際は自分のコントロールの範囲を超えているために衝突し続けます。

これが本当の場合は、別のプロセスを持つという道を辿る必要があると思います。呼び出したコードがスレッドセーフでない場合は、このコードが一度に1つのプロセスによって呼び出されることを確認するだけです。これは、基本的に、別のスレッドで実行することの利点を排除します。

だけでなく、対象プロセス

を殺すために自分の能力を妨げる私はここにあなたのポイントが表示されていません。実行中のすべてのコードを完全に制御できない場合は、安全に処理を終了できるプロセスでのみ、スレッドで安全な方法で実行することはできません。

類似の問題の説明については、this questionも参照してください。

0

スレッドごとに別々のクラスローダーを使用して、独立して保持するサードパーティライブラリを読み込むことができます。

0

リソースを1つのエグゼキュータに入れて、2つのプロセスを並列に実行することはできません。

あなたがそれを行うことができる方法は、エグゼキュータの手段である:

class Foo { 
    private ExecutorService executor = Executors.newSingleThreadExecutor(); 

    public void addTask(Runnable bar) { 
    executor.submit(bar); 
    } 
} 
関連する問題