1
class Untitled {
    public static void main(String[] args) {
        MyRunnable r1 = new MyRunnable();
        Thread t1 = new Thread(r1,"Thread 1:");
        Thread t2 = new Thread(r1,"Thread 2:");
        t1.start();
        t2.start();

    }
}

class MyRunnable implements Runnable
{
    String s1 = "Hello World";
    String s2 = "Hello New World";
    public void run()
    {
        synchronized(s1)
        {
            for(int i =0;i<3;++i)
            System.out.println(Thread.currentThread().getName()+s1);

        }
        synchronized(s2)
        {
            for(int i = 0;i<3;++i)
            System.out.println(Thread.currentThread().getName()+s2);
        }

    }
}

出力:

Thread 1:Hello World
Thread 1:Hello World
Thread 1:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 1:Hello New World
Thread 2:Hello World
Thread 2:Hello New World
Thread 2:Hello New World
Thread 2:Hello New World

ロックオブジェクトが異なるにもかかわらず、 が最初の同期ブロックを実行しているときに、メソッドThread2で 2 番目の同期ブロックを実行できないのはなぜですか。run()Thread1Thread2Thread1

もしそうなら、同期された両方のブロックを同時に実行するにはどうすればよいですか??

4

7 に答える 7

6

スレッド 2 の実行は、スレッド 1 がそのブロックを離れるまで、最初の同期ブロックで待機しますか??

はい、それがアイデアです-スレッド2はブロックを次々に実行します。ブロックされていて最初のものに入ることができない場合は、s1ロックが利用可能になるまでそこで待機します。

もしそうなら、同期された両方のブロックを同時に実行する方法は??

それらを 2 つの異なるランナブルに分割し、それぞれに 1 つのスレッドを使用する必要があります。

于 2013-03-22T10:43:17.030 に答える
3

run メソッド内では、ステートメントが並列ではなく順次実行されるためです。

したがって、スレッド 1 またはスレッド 2 が他の s1 のロックを取得すると、それが解放されるまで待機します。

于 2013-03-22T10:43:08.283 に答える
3

2 つのブロックが交互に並んでいるため、スレッド 2 はブロック 2 を通過する前にブロック 1 を通過する必要があります。

于 2013-03-22T10:44:09.517 に答える
3

Thread1 が最初の同期ブロックを実行しているときに、Thread2 が run() メソッドで 2 番目の同期ブロックを実行できないのはなぜですか

コードは行ごとに実行され、実行は次のブロックにジャンプせず、スレッド 2 はスレッド 1 が最初の同期ブロックを離れるのを待ちます。

スレッド 1 がそのブロックを離れるまで、スレッド 2 の実行は最初の同期ブロックで待機しますか?

はい。

もしそうなら、同期された両方のブロックを同時に実行するにはどうすればよいですか??

したがって、それらを別々の実行可能なインスタンスに保管してください。シーケンス内で次々とではありません。

于 2013-03-22T10:45:25.517 に答える
1

コンパイラがコードを実行するだけです。つまり、コンパイラは、コードが書かれたとおりに順番にコードを実行します。スレッド 2 はコードの最初のブロックをスキップできません。最初のブロックを最初に実行し、次に他のブロックを実行します。

于 2013-03-22T10:46:47.533 に答える
0
class ThreadExample {
    public static void main(String[] args) {
        MyRunnable15756 r1 = new MyRunnable15756();
        Thread t1 = new Thread(r1,"Thread 1:");
        Thread t2 = new Thread(r1,"Thread 2:");
        t1.start();
        t2.start();

    }
}

class MyRunnable15756 implements Runnable
{
    String s1 = "Hello World";
    String s2 = "Hello New World";
    Runnable runnable1 =  new Runnable(){
        @Override
        public void run() {
              synchronized(s1)
                {
                    for(int i =0;i<30;++i)
                    System.out.println(Thread.currentThread().getName()+s1);

                }

        }
    };

    Runnable runnable2 =  new Runnable(){
        @Override
        public void run() {
             synchronized(s2)
                {
                    for(int i = 0;i<30;++i)
                    System.out.println(Thread.currentThread().getName()+s2);
                }

        }
    };
    public void run()
    {

        new Thread(runnable1).start();

        new Thread(runnable2).start();



    }
}
于 2013-03-22T11:08:37.323 に答える
0

両方を同時に実行する例を次に示します。各ループを個別のスレッドに配置しただけでなく、同期の範囲を印刷のみに縮小したことに注意してください。

public class Test {
  static class MyRunnable implements Runnable {
    final String s1 = " Hello World - ";
    final String s2 = " Hello New World - ";
    static final int n = 10;

    @Override
    public void run() {
      // Two loops in two threads.
      new Thread(new Runnable() {
        @Override
        public void run() {
          for (int i = 0; i < n; ++i) {
            // Scope reduced.
            synchronized (s1) {
              System.out.println(Thread.currentThread().getName() + s1 + i);
            }
          }
        }
      }, Thread.currentThread().getName() + "(a)").start();
      // Two loops in two threads.
      new Thread(new Runnable() {
        @Override
        public void run() {
          for (int i = 0; i < n; ++i) {
            // Scope reduced.
            synchronized (s2) {
              System.out.println(Thread.currentThread().getName() + s2 + i);
            }
          }
        }
      }, Thread.currentThread().getName() + "(b)").start();
    }
  }

  public void test() {
    MyRunnable r1 = new MyRunnable();
    Thread t1 = new Thread(r1, "Thread 1:");
    Thread t2 = new Thread(r1, "Thread 2:");
    t1.start();
    t2.start();
  }

  public static void main(String args[]) {
    new Test().test();
  }
}
于 2013-03-22T10:56:01.013 に答える