What is the use of synchronized block inside const

2020-07-08 07:09发布

We can not make constructor synchronized but can write synchronized this inside constructor. In what case such requirement will come ? I am amused.

package com.simple;
public class Test {
    public Test() {
        synchronized (this) {
            System.out.println("I am called ...");
        }
    }

    public static void main(String[] args) {
        Test test=new Test();   
        System.out.println(""+test);
    }

    @Override
    public String toString() {
        return "Test []";
    }
}

7条回答
我欲成王,谁敢阻挡
2楼-- · 2020-07-08 07:16

Well, you could start a new thread within the constructor. It would be highly unusual - and certainly in the code you've provided it would be pointless - but it could happen.

Languages don't typically try to find every possibly thing you could do that would be pointless - it would lead to a very complex language specification. There has to be some degree of thought on the part of the language users, too...

查看更多
可以哭但决不认输i
3楼-- · 2020-07-08 07:18

May be you are changing some common data in constructor that is accessed by multiple threads. Though a better and simple approach would be preferred.

查看更多
太酷不给撩
4楼-- · 2020-07-08 07:19

As far as I understand it can be critical if you deal with static fields inside a constructor. When object is under construction only thread which is creating it has an access to this object, but in case of changes of static field values in the constructor it can be an issue as two different threads can create objects of the same class simultaneously causing conflicts related to static fields. But not sure if it is a good idea to use this for locking

查看更多
Rolldiameter
5楼-- · 2020-07-08 07:27

In normal conditions, there should be no reason why you would do that.

However, if you let the this reference "escape" the constructor (this is bad practice, of course), then you may want to force the client code to wait for the synchronized block to complete before invoking other operations.

For example:

class C {
    public C() {
        // ....
        synchronized(this) {
            someService.doSomethingWith(this);
            // some other critical stuff...
        }
    }

    public synchronized void criticalSection() {
        // ...
    }

}

In this example, if you invoke criticalSection() inside someService, you will be forced to wait until the synchronized block in the constructor is completed.

But again, this is not recommended and you should never allow this to escape the constructor.

查看更多
贼婆χ
6楼-- · 2020-07-08 07:36

I think that Java flexibility allows to do that because inside a constructor you can do almost everything as a normal method (Methods vs Constructors in Java) but, is a bad practice if we are doing it. It's a matter of good practice here, we should no use synchronized blocks in constructors, there is no case where is better doing it inside a constructor.

查看更多
\"骚年 ilove
7楼-- · 2020-07-08 07:37

It could be used to ensure safe publication of non-final fields in the constructor.

public class Test {
    int a;
    public Test() {
        synchronized (this) {
            a = 5;
        }
    }

If another thread receives an object of type Test, and it also synchronizes on that instance of Test, then this creates a happens-before relation between the end of the synchronized block in the constructor, and the beginning of the synchronized block in the other thread:

public class InOneThread {
    public void run() {
        InAnotherThread.test = new Test();
    }
}

public class InAnotherThread {
     public static Test test;

     public void run() {
         if (test == null) {
             // Because assignment to `test` wasn't safely published, the
             // field could be null even if it was assigned "earlier" in real
             // time.
             return;
         }
         synchronized(test) {
             System.out.println(test.a); 
             // If no more modifications were made to 'a', this prints 5
             // (guaranteed). Without the synchronized blocks, this could 
             // print 0 (zero) or 5.
         }
     }
}

However in practice this is almost never useful, since you need to synchronization mechanism to safely pass the instance of Test from one thread to another, and the synchronization mechanism itself almost certainly already introduces a happens-before relationship between the threads.

Still it could have its use in some highly specific concurrency component.

查看更多
登录 后发表回答