0

オブジェクトを作成して、このようなスレッドで実行するとします。

public class Main {

public static void main(String[] args) {
    SomeClass p = new SomeClass (143);
    p.start();
    p.updateNumber(144);

}}

休閑地としてメソッドupdateNumber()を使用してSomeClassで渡されたパラメーターを更新することは可能ですか?

# 更新しました

class SomeClass extends Thread {
     volatile int number ;
     SomeClass (int number ) {
         this.number = number ;
     }

     public void run() {
         while(true){
          System.out.println(number);
           }
     }

  public  void updateNumber(int n){     
          number =n;
          }
  }   

結果:144 144 144 144144..。

ありがとう

4

6 に答える 6

2

はい。ただし、numberas として宣言するvolatileか、(できれば) AtomicLonga の代わりにan を使用する必要がありますlong

于 2011-06-06T01:37:23.830 に答える
2

numberを として宣言しvolatileます。

volatile はいつ必要ですか?

複数のスレッドが同じ変数を使用する場合、各スレッドはその変数のローカル キャッシュの独自のコピーを持ちます。したがって、値を更新するときは、実際にはメイン変数メモリではなくローカル キャッシュで更新されます。同じ変数を使用している他のスレッドは、別のスレッドによって変更された値について何も知りません。この問題を回避するために、変数を volatileとして宣言すると、変数はローカル キャッシュに格納されなくなります。スレッドが値を更新するたびに、メイン メモリに更新されます。したがって、他のスレッドは更新された値にアクセスできます

于 2011-06-06T01:38:00.757 に答える
1

SomeClassRunnable であっても、それは単なる通常のクラスであり、そのオブジェクトは、それを参照する任意のスレッドからアクセスできます。あなたの例では。どこでもフォームを呼び出していませんがupdateNumber()、p.start() の後に呼び出すと、実際にインスタンスを作成したスレッドからアクセスしています。を呼び出している場合はupdateNumber()run()開始したばかりのスレッドからアクセスしています。

もう1つの質問は、セットアップで複数のスレッドから変更しても安全ですか? 答えはノーだ。として宣言する必要がありますvolatile(たとえば)、またはsynchronize現在の値に基づいて変更する場合。どのように、何を同期するかは、実際に何を行っているかによって異なります。

于 2011-06-06T01:39:04.057 に答える
1

volatile次のすべての基準が満たされている場合、キーワードを使用できます。

  • 変数への書き込みは現在の値に依存しません。または、単一のスレッドのみが値を更新するようにすることができます。
  • 変数は、他の状態変数を持つ不変条件に参加しません
  • 変数がアクセスされている間は、他の理由でロックする必要はありません

それ以外の場合は、何らかの同期ポリシーを使用することをお勧めします

class SomeClass implements Runnable {
    private Integer number;
    SomeClass (int number) {
        this.number = Integer.valueOf(number);
    }

    @Override
    public void run() {
        while(true){
           System.out.println(getNumber());
        }
    }

  public void updateNumber(int n){
      synchronized(number){
          number = Integer.valueOf(n);
      }
  }     

  public int getNumber(){
      synchronized(number){
          return number.intValue();
      }
  }
}
于 2011-06-06T01:59:02.690 に答える
1

言及されていないが、上記の同期の代わりに使用する必要があるもう 1 つのオプションは、Java 1.5 で Doug Lee によって導入された Concurrency パッケージを利用することです。

Atomic クラスを使用してください。これらは、同時実行の問題をすべて処理します。(ある程度まで)

このようなもの:

 private AtomicInteger number = new AtomicInteger(0);

 public void updateNumber(int n) {
   number.getAndSet(n);
 }

 public int getNumber() {
   return number.get();
 }

Java 1.6 AtomicInteger JavaDoc

実際のJava並行性

私の意見では、Java Concurrency in Practice は Java のスレッド化に関する最高の本です。

于 2011-06-06T07:50:36.063 に答える
0

はい、呼び出すことはできますがp.updateNumber(...)、スレッド同期の問題に注意する必要があります。

于 2011-06-06T01:39:13.700 に答える