0

HashSet の 10,000 スレッド (つまり 10,000 回) で Singleton オブジェクトを格納します。驚くべきことに、HashSet は Object が Singleton であることを認識できず、同じオブジェクト インスタンスを 2 回格納することがあります。また、オブジェクトを一度格納しても、その size() メソッドが値 2 または 3 を返す場合があります。

私のシングルトンクラスは次のとおりです:-

public class Singleton {

  private Singleton() {

    System.out.println("Singleton--- It runs just once");

    }

   private static class StageSingletonHolder {

    static Singleton instance = new Singleton();

    }


   public static Singleton getInstance() {

    return StageSingletonHolder.instance;
  }


 }

メイン クラスのスレッドに実行メソッドを提供する RunObject:-

import java.util.HashSet;
import java.util.Set;


 public class RunObject implements Runnable{
  Singleton singleton;
  public static Set<Singleton> set = new HashSet<Singleton>();


  public void run(){

      singleton = Singleton.getInstance();
      set.add(singleton);       
    }



    public int numberOfSingletons(){

    for(Singleton single:set){

        System.out.println(single);

        }

    System.out.println("set size : "+set.size());

   }

 }

私のメインクラスは: -

  public class MainObject {

   public static void main(String[] args){
   RunObject runObject = null;
   Thread t;
   int i = 0;
   while(i++ < 10000){
    runObject = new RunObject();
    t = new Thread(runObject);
    t.start();
    }

  }
 }

ここで、場合によっては、同じオブジェクトが複数回格納されます。コンストラクターが 1 回だけ実行されるため、Singleton ロジックが正しく機能することはわかっています。これは、コンストラクターがステートメントを 1 回だけ出力することから明らかです。

この不一致の理由は何でしょうか?

4

1 に答える 1

4

HashSetスレッドセーフではありません。追加を同期するか、シングルトンを格納するための適切な同時収集を使用する必要があります。

于 2013-09-04T07:04:45.300 に答える