2017-03-12 4 views
0

私は、さまざまなシングルトンパターンを作成し、数百万のスレッドを使ってブレークをチェックしようとしています。私はこれが最終的にBill Pughを実装するようになると思っていました。しかし、私は古典的なものを壊すことさえできません。古典的な遅延初期化を壊すことはできません。シングルトン

シングルトン:以前は100万のスレッドを試しましたが、すべて同じハッシュコードを使用していました。だから私は10秒間スリープ状態にして、両方のスレッドがヌルチェック条件を入力するようにしましたが、すべてが欲求不満になりました。

package demo2; 

public class Singleton { 

    private static Singleton soleInstance = null; 

    private Singleton() throws InterruptedException { 

    } 

    public static Singleton getInstance() throws InterruptedException { 

     if (soleInstance == null) { 

      Thread.sleep(10000); 

      soleInstance = new Singleton(); 

     } 

     return soleInstance; 

    } 

} 

テストクラス:地獄はそれを私破るにはどうすればよい

package demo2; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.stream.Collectors; 

class Test { 

    public int makeSingleton() throws InterruptedException { 

     Singleton s = Singleton.getInstance(); 

     return s.hashCode(); 

    } 

    public static void main(String[] args) throws InterruptedException, ExecutionException { 

     Test t = new Test(); 

     ExecutorService executor = Executors.newFixedThreadPool(2); 

     List<Integer> list = new ArrayList<>(); 

     for (int i = 0; i < 2; i++) { 

      Future<Integer> future = executor.submit(new Callable<Integer>() { 

       public Integer call() throws InterruptedException { 

        return t.makeSingleton(); 
       } 
      }); 

      list.add(future.get()); 
     } 

     executor.shutdown(); 

     List<Integer> list2 = list.stream().distinct().collect(Collectors.toList()); 

     System.out.println(list2); 

    } 
} 

答えて

2

以下のコードが有効です。

コードを変更してください。あなたは内側のメソッドだけを呼び出すことがありますし、結果を得るのを待っています&ループカウントは増加しません。

ExecutorService executor = Executors.newFixedThreadPool(2); 

     List<Future<Integer>> list = new ArrayList<Future<Integer>>(); 

     for (int i = 0; i < 5; i++) { 

      Future<Integer> future = executor.submit(new Callable<Integer>() { 

       public Integer call() throws InterruptedException { 

        return Singleton.getInstance().hashCode(); 
       } 
      }); 

      list.add(future); 
     } 

     executor.shutdown(); 

     Set<Integer> output = new HashSet<Integer>(); 
     for(Future<Integer> future : list){ 
      output.add(future.get()); 
     } 

     System.out.println(output); 
+0

このコードを試してみてください、まだ私のための単一のハッシュコードを返します。 'Thread.sleep'はデフォルトで現在のスレッドもスリープしません。 – garg10may

+0

私のシステムで試してみました。はい、どちらも同じことをします。私は両方のステートメントで自分のアンサーチェックを掲載しました。 – cody123

+0

「スリープ」が必要なのはなぜだと思いますか? 'Thread'作成コードを短縮できますか?それらのRunnableは同じことをしています。 –

1

この確認してください:あなたは

Future<Integer> future = executor.submit(new Callable<Integer>() 

を使用している場合、それは結果の返却まであなたのスレッドをブロックします

/** 
* <p> 
* If you would like to immediately block waiting 
* for a task, you can use constructions of the form 
* {@code result = exec.submit(aCallable).get();} 
*/ 
<T> Future<T> submit(Callable<T> task); 

を。

あなたは、古典的なシングルトンパターンを破るしたい場合は、無

public class BreakSingleton { 

    public MySingleton makeSingleton() throws InterruptedException { 
     MySingleton s = MySingleton.getInstance(); 
     return s; 
    } 

    public static void main(String[] args) throws Exception { 
     BreakSingleton t = new BreakSingleton(); 
     ExecutorService executor = Executors.newFixedThreadPool(2); 
     final List<MySingleton> list = new ArrayList<>(); 
     System.out.println(Thread.currentThread().getName()); 

     for (int i = 0; i < 2; i++) { 
      executor.submit(new Callable<MySingleton>() { 
       public MySingleton call() throws InterruptedException { 
        MySingleton mySingleton = t.makeSingleton(); 
        list.add(mySingleton); 
        return mySingleton; 
       } 
      }); 
     } 
     executor.shutdown(); 
     Thread.sleep(5000); 
     System.out.println(list); 
    } 
} 

class MySingleton { 
    private static MySingleton instance = null; 

    private MySingleton() { 
    } 

    public static MySingleton getInstance() throws InterruptedException { 
     System.out.println(Thread.currentThread().getName()); 
     if (instance == null) { 
      Thread.sleep(3000); 
      System.out.println(Thread.currentThread().getName()); 
      instance = new MySingleton(); 
     } 
     return instance; 
    } 
} 
関連する問題