public class PlanetInfo {
String planetName="";
int a;
int b;
int c;
PlanetInfo(planetname){
planetName = planetname;
if(planetName.equals("earth")){
a=1;
//....
}
else if(planetName.equals("mars")){
a=2;
//....
}
}
}
public final class Infos {
static final LinkedList<PlanetInfo> planets = new LinkedList<PlanetInfo>();
private static synchronized PlanetInfo internal_getPlanetInfo(String planetName){
for(int i=0;i<planets.size();i++){
if(planets.get(i).planetName.equals(planetName)){
//return existing PlanetInfo:
return planets.get(i);
}
}
//if not found then create and return a new one:
return new PlanetInfo(planetName);
}
public static PlanetInfo getPlanetInfo(String planetName){
return internal_getPlanetInfo(planetName);
}
}
public class Foo {
PlanetInfo planetinfo = null;
public Foo(aplanet){
planetInfo = Infos.getPlanetInfo(aplanet);
}
public void dosomthing(){
if(planetInfo.a==1){//please, do not wonder about thread-safe here, it's just a simplification...
// etc....
}
}
}
PlanetInfo
新しいニーズが作成されることはまれですが、発生します。作成されてPlanetInfo
追加されるとInfos.planets
、決して削除されません。ほとんどの場合、Infos.planets
実際には読み取り専用です。
のインスタンスを持つ多くのスレッドがありFoo
、それらはすべてオブジェクトへのポインタを必要としPlanetInfo
ます。ご覧のとおり、internal_getPlanetInfo
同期されています。
コードを変更できるかどうか疑問に思うので、目的のPlanetInfo
. 最初の試行はAsynchronouslyになり、(見つからない場合は) 2 回目はsynchronouslyになります。そう... メソッドgetPlanetInfo
は、メソッドと同じ for ループを変更しますinternal_getPlanetInfo
。したがって、ほとんどの場合、スレッドは互いにロックしません。
私が念頭に置いているのは、スレッドには の「古い」コピーがある可能性があるということInfos.planets
です。この「古い」コピーの唯一の潜在的な問題は、しばらくしてから追加された項目が失われることです。そのため、目的のアイテムが見つからない場合は、 「マスター」コピーを使用して探します。
public static PlanetInfo getPlanetInfo(String planetName){
//try to find it Asynchronously:
for(int i=0;i<planets.size();i++){
if(planets.get(i).planetName.equals(planetName)){
return planets.get(i);
}
}
//if not found then do it synchronously:
return internal_getPlanetInfo(planetName);
}
コメントをいただければ幸いです。
私がやります。