3

スレッド A とスレッド B の 2 つのスレッドがあるとします。

スレッド A がメインのメソッドであり、大きなデータ構造が含まれています。

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

これのポイントは、スレッド B でデータ構造全体を複製したり、スレッド B が使用するデータ構造から関連情報を引き出すのに多くの時間を費やしたりする必要を回避することです。

どちらのスレッドもデータを変更していないことに注意してください

4

5 に答える 5

3
  1. Java では、ポインターという用語は使用されませんが、参照です。
  2. 他のオブジェクトと同様に、別のスレッドに渡すことができます。Java の (最終ではない) クラスと同様に、拡張、メンバーの追加、コンストラクターの追加などを行うことができます。
  3. (データを変更する必要がある場合) 同時実行の問題がないことを確認する必要があります。
于 2012-04-19T22:48:52.597 に答える
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();

  }

}
于 2012-04-19T22:48:59.123 に答える
1

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

于 2012-04-19T22:49:38.330 に答える
0

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

可変オブジェクトへの参照を共有したい場合は、たとえば、synchronized または volatile キーワードを使用して、適切な同期を使用する必要があります。

データを安全に共有する簡単な方法は、 AtomicReferenceや ConcurrentHashMapなどの java.util.concurrent パッケージのユーティリティを使用することですが、共有するオブジェクトが変更可能である場合は、依然として細心の注意を払う必要があります。

于 2012-04-19T23:20:55.517 に答える
0

共有データに変更を加えていない場合は、共有参照を持つことができ、大きなオーバーヘッドはありません。

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

于 2012-04-20T11:31:22.200 に答える