2012-04-19 2 views
2

は、スレッドAとスレッドBの2つのスレッドがあるとします。スレッド間の読み取り専用参照の共有

スレッドAは主な方法であり、大きなデータ構造を含んでいます。

はそのように、両方のスレッドがデータ構造から読み取ることができるBを通すために、第2のスレッドを作成し、(Aのスレッドに対してローカル)データ構造のアドレス(ポインタ)を通過することができますか?

これのポイントは

どちらのスレッドがあることに注意してくださいを使用するために、スレッドB上のデータ構造全体を複製したり、スレッドBのためのデータ構造から関連情報を引っ張って多くの時間を費やす必要性を回避するためでありますデータを変更しています

+2

Javaにはポインタがありません。 – Perception

+0

@Perception、Correct、間接的に参照渡しが可能です。 http://stackoverflow.com/questions/40480/is-java-pass-by-reference – jli

答えて

1

これは、従来の意味でポインタに直接アクセスすることはできないため、Javaでは参照として知られています。 (ほとんどの場合、それはすべての参照は、常に値で渡されるポインタであり、唯一の法的な操作がデリファレンスにある。それはC++と同じではないので、それを考えるために、「安全」の「参照。」)

スレッド間で参照を確実に共有できます。ヒープ上にあるものは、そのスレッドへの参照を取得できるすべてのスレッドが参照して使用できます。静的な場所に置くか、データを指すようにRunnableの参照値を設定します。

public class SharedDataTest { 

    private static class SomeWork implements Runnable { 
    private Map<String, String> dataTable; 

    public SomeWork(Map<String, String> dataTable) { 
     this.dataTable = dataTable; 
    } 

    @Override 
    public void run() { 
     //do some stuff with dataTable 
    } 
    } 

    public static void main(String[] args) { 

    Map<String, String> dataTable = new ConcurrentHashMap<String, String>(); 

    Runnable work1 = new SomeWork(dataTable); 
    Runnable work2 = new SomeWork(dataTable); 

    new Thread(work1).start(); 
    new Thread(work2).start(); 

    } 

} 
+0

私は誰もこれのためのコードを書くことを期待していない。誰もがすばらしい答えをくれてくれてありがとう。 – Jdak

3
  1. Javaでは、ポインタという用語は使用されていませんが、参照されています。
  2. 別のスレッドに、他のオブジェクトのように、それを通過することが可能です。 Javaで任意の(非最終)クラスとして、あなたはそれを拡張することができ、メンバーを追加し、コンストラクタを追加するなど
  3. (あなたがデータを変更する必要がある場合)あなたは何の並行性の問題がないことを確認する必要があります。
1

は、はい、それは可能であると行うには通常のことですが、あなたは、両方のスレッドがデータの最新のバージョンまで見ていることを確認するために適切な同期を使用していることを確認する必要があります。

0

不変オブジェクトへの参照を共有しても安全です。おおまかに言えば、不変オブジェクトは、の構築後に状態を変更しないオブジェクトです。意味的に不変なオブジェクトは、不変のオブジェクトを参照する最終フィールドのみを含む必要があります。

あなたは、同期や揮発性のキーワードを使用して、たとえば、適切な同期を使用する必要が変更可能なオブジェクトへの参照を共有したい場合。安全にデータを共有する

簡単な方法は、しかし、あなたはまだあなたが共有オブジェクトが変更可能である場合には非常に注意する必要があり、java.util.concurrentパッケージのようなAtomicReferenceかのConcurrentHashMapからユーティリティを使用することです。

0

共有データを変更していない場合は、共有参照があり、重大なオーバーヘッドはありません。

ただし、共有オブジェクトを同時に変更する場合は、javaで提供されているデータ構造(Collectionsのファクトリメソッドを参照)を使用するか、java.util.concurrent.locks.ReentrantLockなどのカスタム同期スキームを使用することができます。

関連する問題