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