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执行run()方法中的第二个同步块。执行是否在第一个同步块处等待直到离开该块?Thread1Thread2Thread1

如果是这样如何使两个同步块同时运行?

4

7 回答 7

6

Thread2 的执行是否在第一个同步块处等待,直到 Thread1 离开该块?

是的,这就是想法 - thread2 一个接一个地执行块。如果它被阻塞并且无法进入第一个,它将在那里等待直到s1锁可用。

如果是这样如何使两个同步块同时运行?

您需要将它们拆分为两个不同的可运行文件,并为每个文件使用一个线程。

于 2013-03-22T10:43:17.030 回答
3

因为在 run 方法中的语句是按顺序执行的,而不是并行执行的。

因此,线程 1 或线程 2 获得 s1 other 的锁的人将等待直到它被释放。

于 2013-03-22T10:43:08.283 回答
3

这两个块是一个接一个,这意味着线程 2 必须先通过块 1,然后才能通过块 2

于 2013-03-22T10:44:09.517 回答
3

为什么Thread1在执行第一个同步块时,线程2不能在run()方法中执行第二个同步块

代码逐行执行,执行不会跳转到下一个块,线程 2 等待线程 1 离开第一个同步块。

Thread2 的执行是否在第一个同步块处等待,直到 Thread1 离开该块

是的。

如果是这样如何使两个同步块同时运行?

所以将它们保存在单独的可运行实例中。并且不是在一个序列中一个接一个。

于 2013-03-22T10:45:25.517 回答
1

它只是编译器执行代码,即编译器按它们编写的方式按顺序执行代码。线程 2 不能跳过第一个代码块。它将首先执行第一个块然后其他块。

于 2013-03-22T10:46:47.533 回答
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 回答
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 回答