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

Java在同步块中调用其他方法,java,multithreading,synchronization,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

我编写了一个工人类,如下所示:

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);
      }
    }
  }
}
我在main方法中启动两个新线程,并在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, 整个实例被其他线程阻塞,并将通过离开同步块来释放。 如果我在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

有人能告诉我它是怎么工作的吗?谢谢

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


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

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


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

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

  • 公共同步void methodOne(Worker-sWorker){ sWorker.doSomething();}

在上面的代码中,我们只是传递我们希望同步的实例。

java中的synchronized关键字有两种使用方式 1.在实例级别 2.班级层面

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

  • 公共同步void methodOne(Worker-sWorker){ sWorker.doSomething();}

在上面的代码中,我们只是传递我们希望同步的实例。

调用同步方法只会阻塞同一实例上的其他同步器。由于
methodTwo()
未同步,因此它不会被阻止。如果
doSomething
是同步的,而不是
methodOne
,它应该可以正常工作。关于计算部分,如果您只是想让线程在那里花费一些时间,您可以尝试使用
Thread.sleep
。John Bollinger的答案可以归结为:
synchronized(foo){…}
防止其他线程同时对同一对象
foo
执行
synchronized(foo){…}
。它不会阻止其他线程执行任何其他操作。调用同步方法只会阻止同一实例上的其他同步器。由于
methodTwo()
未同步,因此它不会被阻止。如果
doSomething
是同步的,而不是
methodOne
,它应该可以正常工作。关于计算部分,如果您只是想让线程在那里花费一些时间,您可以尝试使用
Thread.sleep
。John Bollinger的答案可以归结为:
synchronized(foo){…}
防止其他线程同时对同一对象
foo
执行
synchronized(foo){…}
。它不会阻止其他线程执行任何其他操作。
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