简体   繁体   English

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

[英]Java calling other methods in synchronized block

I have written a worker class looking like this: 我写了一个工人阶级,看起来像这样:

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

Afterwards I call the worker with following class: 之后,我用以下课程给工人打电话:

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

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

I start two new threads in my main-method and call the two methods in SynchronizedMultiMethod: 我在主方法中启动了两个新线程,并在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();
      }
}

If I execute this code, I get this output: 如果执行此代码,则会得到以下输出:

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
...

I'm a little bit confused because I thaught that if I use synchronized on an instance method, the whole instance is blocked for other threads and will be released by leaving the synchronized block. 我有些困惑,因为我想如果我在实例方法上使用同步,则会为其他线程阻塞整个实例,并通过保留同步块将其释放。 If I use a second synchronized on methodTwo(), it works fine: 如果我在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

Can anybody tell me how it works? 谁能告诉我它是如何工作的? thx! 谢谢!

You are mistaken about the meaning and usage of synchronized . 你错了约的意义和用法synchronized If you declare a method synchronized , it is functionally equivalent to putting a synchronized(this) {...} block around the entire contents of the method body. 如果您声明一个方法为synchronized ,则该函数在功能上等同于在方法主体的整个内容周围放置一个synchronized(this) {...}块。 This interacts with other synchronized methods of the same object, and with other blocks synchronized on the same object, but it has no effect on other code. 这与同一对象的其他同步方法以及在同一对象上同步的其他块进行交互,但对其他代码没有影响。

In particular, methods and blocks that are not synchronized on the same object -- or are not synchronized at all -- are not excluded from running concurrently with a synchronized method of a given object. 特别是,未在同一对象上同步的方法和块或根本未同步的方法和块不会与给定对象的同步方法并发运行。 Thus, sync.methodTwo() , which is not synchronized, can run concurrently with sync.MethodOne() . 因此, sync.methodTwo()这是不同步的,可以同时用运行sync.MethodOne() One of many ways to prevent this would be to make SynchronizedMultiMethod.methodTwo() synchronized as well. 防止这种情况的许多方法之一是使SynchronizedMultiMethod.methodTwo()同步。

Synchronized keyword in java is used in two ways 1.At Instance level 2.At Class level Java中的同步关键字有两种使用方式:1.在实例级别2.在类级别

In the instance level ,we are passing the instance in the synchronized method like synchronized(this) 在实例级别,我们以同步方法(例如synced(this))传递实例

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

In above code we are just passing the instance which we are willing to synchronized. 在上面的代码中,我们只是传递了我们愿意同步的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM