1

次のコードでは、2 つのスレッドのうちの 1 つだけがhalt()関数に入り、プログラムを停止すると予想していました。synchronizedしかし、両方のスレッドがHalt() 関数に入っているように見えます。なぜこれが起こっているのでしょうか??

package practice;

class NewThread implements Runnable {
  String name; // name of thread
  Thread t;
  boolean suspendFlag;

  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("New thread: " + t);
    suspendFlag = false;
    t.start(); // Start the thread
  }

  // This is the entry point for thread.
  public void run() {
    try {
      for(int i = 15; i > 0; i--) {
        System.out.println(name + ": " + i);
        Thread.sleep(200);
        Runtime r = Runtime.getRuntime();
        halt();
      }
    } catch (InterruptedException e) {
      System.out.println(name + " interrupted.");
    }
    System.out.println(name + " exiting.");
  }

  synchronized void halt() throws InterruptedException
  {
      System.out.println(name + " entered synchronized halt");
      Runtime r = Runtime.getRuntime();
      Thread.sleep(1000);
      r.halt(9);
      System.out.println(name + " exiting synchronized halt"); // This should never execute
  }
}

class Practice{
  public static void main(String args[]) {
    NewThread ob1 = new NewThread("One");
    NewThread ob2 = new NewThread("Two");

    // wait for threads to finish
    try {
      System.out.println("Waiting for threads to finish.");
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Main thread Interrupted");
    }

    System.out.println("Main thread exiting."); // This should never execute
  }
}
4

5 に答える 5

7

synchronized はメソッドをロックするのではなく、オブジェクトをロックします。

メソッドは 1 つですが、オブジェクトは 2 つです。各スレッドは独自のオブジェクトをロックし、halt() を呼び出します。

于 2012-09-13T17:30:42.590 に答える
2

同期は各オブジェクトで行われます。2 つのオブジェクトがある場合、2 つのスレッドがhalt()同時にメソッドに入る可能性があります。メソッドを静的にして、目的を達成できます。静的にすることにより、 のインスタンス数に関して一意である対応するClassオブジェクト ( )にロックがかかります。 NewThreadOne.classNewThreadOne

于 2012-09-13T17:31:37.080 に答える
1

あなたは2 objects彼ら2 threadsmonitor lock....

したがって、コードは正常に機能し、各スレッドは独自のオブジェクトのロックにアクセスして halt()メソッドにアクセスします....

では、オブジェクトのロックsynchonized keywordを達成します。これにより、スレッドはそのクラス内へのアクセスを取得します......synchronized methods or atomic statements

于 2012-09-13T17:32:01.570 に答える
1

synchronizedメソッドはこれをロックに使用しています。あなたの場合、2 つのスレッド インスタンスを構築しているため、2 つの異なるオブジェクトがあるため、同じオブジェクトをロックしていません。halt期待どおりの同期動作を実現するには、メソッドを作成する必要がありますstatic

于 2012-09-13T17:33:19.577 に答える
1

文字列は不変オブジェクトであり、リテラル文字列とインターンされた文字列は文字列プールに格納されるため、文字列オブジェクトを Java 同期ブロックのロックとして使用することはお勧めしません。したがって、コードの他の部分またはサードパーティのライブラリがロックと同じ文字列を使用した場合、それらは完全に無関係であるにもかかわらず同じオブジェクトでロックされ、予期しない動作やパフォーマンスの低下につながる可能性があります。String オブジェクトの代わりに、Java で同期ブロックの同期に new Object() を使用することをお勧めします。

于 2012-09-13T17:36:14.410 に答える