有什么用内部构造synchronized块?(What is the use of synchron

2019-08-17 03:05发布

我们不能构造synchronized但可以写synchronized这里面的构造。 在什么情况下,这样的规定会来吗? 我觉得好笑。

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 []";
    }
}

Answer 1:

好了,你可以开始在构造函数中一个新的线程。 这将是极不寻常的 - 当然在你的代码已经提供这将是毫无意义的 - 但它可能发生。

语言通常不会试图找到每一个可能的事你能做到这将是毫无意义-这将导致一个非常复杂的语言规范。 必须有对语言使用者的部分一定程度的思想,太...



Answer 2:

同步上this是不好的做法的标志,因为这将意味着你正在泄漏this出构造的:这是你可以有相同的对象上一些其他的代码同步的唯一途径。

同步对其他一些常见的锁,但是,可能是合法的:构造的确是我的涉及调用,需要这样的同步一些代码。



Answer 3:

可能是你改变了这一切是由多个线程访问在构造函数中一些常见的数据。 虽然一个更好的和简单的方法将是首选。



Answer 4:

在正常情况下,应该没有理由你要这么做。

但是,如果你让this参考“逃离”的构造(这是不好的做法,当然的),那么你可能需要强制客户端代码等待synchronized块调用其他操作之前完成。

例如:

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

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

}

在这个例子中,如果你调用criticalSection()someService ,你将不得不等待,直到在构造函数中的synchronized块完成。

但同样,不建议这样做,你永远不应该允许this逃避的构造。



Answer 5:

据我理解,如果你处理一个构造函数中静态字段也可以是至关重要的。 当对象是正在建设中只有线程这是创造它有这个对象的访问,但在构造函数中的静态字段值的变化的情况下,它可以是一个问题,因为两个不同的线程可以创建同一个类的对象同时引起相关冲突以静态字段。 但不知道这是否是使用锁定一个好主意



Answer 6:

它可以被用来确保在构造非最终场的安全出版物。

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

如果另一线程接收类型测试的目的,并且它也同步上的该实例Test ,则这产生了之前发生的的端部之间关系synchronized在构造块,且所述的开始synchronized块中的其他线程:

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

然而在实践中,这是几乎从来没有用,因为你需要同步机制,以安全地从一个线程通过测试实例到另一个,并且同步机制本身几乎可以肯定已经引入了之前发生的线程之间的关系。

不过它也有其在一些非常具体的并发组件使用。



文章来源: What is the use of synchronized block inside constructor?