Java 此同步代码是否导致不必要的线程等待?

Java 此同步代码是否导致不必要的线程等待?,java,multithreading,Java,Multithreading,我们有一个应用程序,它有一个类,其中包含通过数据库填充的成员。这是一个典型的例子 private AtomicBoolean data1Initialized = new AtomicBoolean(false); protected SomeSynchronizedDataStructure<Object> data1 = <initializeit>; protected final synchronized void initData1() { if (d

我们有一个应用程序,它有一个类,其中包含通过数据库填充的成员。这是一个典型的例子

private AtomicBoolean data1Initialized = new AtomicBoolean(false);
protected SomeSynchronizedDataStructure<Object> data1 = <initializeit>;

protected final synchronized void initData1() {
    if (data1Initialized.compareAndSet(false, true)){
        // Populate data1 data structure from database
    }
}
public SomeSynchronizedDataStructure<Object> getData1(){
    initData1();
    return data1;
}
private AtomicBoolean data1Initialized=新的AtomicBoolean(false);
受保护的SomeSynchronizedDataStructure data1=;
受保护的最终同步void initData1(){
if(数据1初始化。比较数据集(假、真)){
//从数据库填充data1数据结构
}
}
公共SomeSynchronizedDataStructure getData1(){
initData1();
返回数据1;
}
我们对数据1,数据2,数据3有相同的模式。。。达坦。每个数据结构彼此不相关,它们只是在同一个类中。跨多个线程访问此数据。有关此模式的几个问题:

同步这些方法将使线程必须等待对所有不同的
dataN
s进行布尔检查,对吗?哪些是不必要的

数据结构是否需要同步?在应用程序的整个生命周期内,数据不会更改。我认为只有初始化它才需要同步,访问可能会发生不同步

对我个人来说最重要的


这会导致僵局吗?我认为没有,但我对线程没有经验。

当您在创建类时初始化时,您需要的只是:

public class DataHolder {
    // Note: 'final' is needed to ensure value is committed to memory before DataHolder
    private final SomeSynchronizedDataStructure<Object> data1 = <initializeit>;

    public SomeSynchronizedDataStructure<Object> getData1(){
        return data1;
    }
}
如果您确实想进行延迟加载,只需使用synchronized:

public class DataHolder {
    private SomeSynchronizedDataStructure<Object> data1;

    public synchronized SomeSynchronizedDataStructure<Object> getData1() {
        // synchronized guarantees each thread will see "data1" just as the
        // last thread left it.
        if(data1 == null) {
            data1 = initializeit();
        }
        return data1;
    }
}
公共类数据持有者{
私有SomeSynchronizedDataStructure数据1;
公共同步的SomeSynchronizedDataStructure getData1(){
//synchronized保证每个线程将看到“data1”,就像
//最后一个线程离开了它。
if(data1==null){
data1=初始化ID();
}
返回数据1;
}
}

当您在创建类时初始化时,您只需要:

public class DataHolder {
    // Note: 'final' is needed to ensure value is committed to memory before DataHolder
    private final SomeSynchronizedDataStructure<Object> data1 = <initializeit>;

    public SomeSynchronizedDataStructure<Object> getData1(){
        return data1;
    }
}
如果您确实想进行延迟加载,只需使用synchronized:

public class DataHolder {
    private SomeSynchronizedDataStructure<Object> data1;

    public synchronized SomeSynchronizedDataStructure<Object> getData1() {
        // synchronized guarantees each thread will see "data1" just as the
        // last thread left it.
        if(data1 == null) {
            data1 = initializeit();
        }
        return data1;
    }
}
公共类数据持有者{
私有SomeSynchronizedDataStructure数据1;
公共同步的SomeSynchronizedDataStructure getData1(){
//synchronized保证每个线程将看到“data1”,就像
//最后一个线程离开了它。
if(data1==null){
data1=初始化ID();
}
返回数据1;
}
}
同步这些方法将使线程必须等待所有不同数据的布尔检查,对吗

哪些是不必要的

是的,这是不必要的,因为数据是不相关的

数据结构是否需要同步?在应用程序的整个生命周期内,数据不会更改。我认为只有初始化它才需要同步,访问可能会发生不同步

再一次,正确。BarrySW19的答案为您提供了在不同步的情况下安全初始化它的模式

对我个人来说最重要的

这会导致僵局吗?我想没有,但我对线程没有经验

它本身不会造成僵局。但是,如果其中一个data init方法调用其他在另一个监视器上同步的东西(称为m),同时其他线程拥有m,并且现在尝试初始化其中一个DataN,这就是死锁

同步这些方法将使线程必须等待所有不同数据的布尔检查,对吗

哪些是不必要的

是的,这是不必要的,因为数据是不相关的

数据结构是否需要同步?在应用程序的整个生命周期内,数据不会更改。我认为只有初始化它才需要同步,访问可能会发生不同步

再一次,正确。BarrySW19的答案为您提供了在不同步的情况下安全初始化它的模式

对我个人来说最重要的

这会导致僵局吗?我想没有,但我对线程没有经验


它本身不会造成僵局。但是,如果其中一个data init方法调用其他在另一个监视器上同步的东西(称为m),同时其他线程拥有m,现在尝试初始化其中一个DataN,这就是死锁。

hmm我猜填充数据基本上是读取数据,除非你改变数据,否则你不需要同步。经验法则:如果它在生命周期内不被写入,就没有必要同步它。你不需要“同步”和原子布尔。嗯,我猜填充数据基本上是读取数据,除非您以某种方式更改数据,否则您不需要同步。经验法则:如果数据在其生命周期内不写入,则无需进行同步。无论如何,您不需要“同步”和原子布尔。