Java 在同步块中调用其他方法

Java calling other methods in synchronized block

我写了一个工人 class 看起来像这样:

public final class Worker
{
  private static final int    LOOP_COUNT    = 10;
  private static final int    COMPUTE_COUNT = 1000;
  private static final Random RANDOM        = new Random();
  private static final int    BUFFER_SIZE   = 4;

  /**
   * do a little bit of calculation and write the thread’s name to stdout
   */
  public static void  doSomething()
  {
    for (int i = 0; i < LOOP_COUNT; i++)
    {
      System.out.println("Thread " + Thread.currentThread().getName()
          + " doing something: " + i);
      System.out.flush();

      for (int j = 0; j < COMPUTE_COUNT; j++)
      {
        final byte[] buffer = new byte[BUFFER_SIZE];
        RANDOM.nextBytes(buffer);
        final BigInteger b1 = new BigInteger(buffer);
        b1.pow(128);
      }
    }
  }
}

之后我打电话给工人 class:

public class SynchronizedMultiMethod
{
  public synchronized void methodOne()  
  {
    Worker.doSomething();
  }

  public void methodTwo()
  {
    Worker.doSomething();
  }
}

我在主方法中启动了两个新线程,并在 SynchronizedMultiMethod 中调用了两个方法:

public class Main {

    public static void main(String[] args) throws InterruptedException
      {
        final SynchronizedMultiMethod sync = new SynchronizedMultiMethod();

        final Thread t1 = new Thread()
          {
            public void run()
            {   
                sync.methodOne();
            }
          };

        final Thread t2 = new Thread()
          {
            public void run()
            {

              sync.methodTwo();
            }
          };

        t1.start();
        t2.start();
      }
}

如果我执行这段代码,我得到这个输出:

Thread Thread-1 doing something: 0
Thread Thread-0 doing something: 0
Thread Thread-1 doing something: 1
Thread Thread-1 doing something: 2
Thread Thread-1 doing something: 3
Thread Thread-0 doing something: 1
Thread Thread-0 doing something: 2
Thread Thread-1 doing something: 4
...

我有点困惑,因为我认为如果我在实例方法上使用同步, 整个实例被其他线程阻塞,将通过离开同步块来释放。 如果我在 methodTwo() 上使用第二个同步,它工作正常:

Thread Thread-0 doing something: 0
Thread Thread-0 doing something: 1
Thread Thread-0 doing something: 2
Thread Thread-0 doing something: 3
Thread Thread-0 doing something: 4

谁能告诉我它是如何工作的?谢谢!

您对synchronized的含义和用法有误。如果声明一个方法 synchronized,它在功能上等同于在方法主体的整个内容周围放置一个 synchronized(this) {...} 块。这与同一对象的其他同步方法交互,并与同一对象上的其他同步块交互,但对其他代码没有影响。

特别是,在同一对象上不同步的方法和块——或者根本不同步的——不会被排除在运行与给定对象的同步方法并发的范围之外。因此,未同步的 sync.methodTwo() 可以与 sync.MethodOne() 同时 运行。防止这种情况的许多方法之一是使 SynchronizedMultiMethod.methodTwo() 也同步。

java中的synchronized关键字有两种用法 1.At 实例级别 2.At Class 级别

在实例级别,我们在同步方法中传递实例,例如 同步(这)

  • public synchronized void methodOne(Worker sWorker) { sWorker.doSomething(); }

在上面的代码中,我们只是传递了我们愿意同步的实例。