Java在synchronized块中调用其他方法

时间:2015-01-06 18:29:32

标签: java multithreading synchronization

我写了一个看起来像这样的工人阶级:

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);
      }
    }
  }
}

之后我用以下课程给工人打电话:

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

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

我在main-method中启动了两个新线程,并在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
...

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

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

有谁可以告诉我它是如何工作的?谢谢!

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

java中的同步关键字有两种使用方式 1.实例级别 2.班级

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

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

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