Suppliers

JavaDoc

こういうindexを増やしながら値を返すSupplierがあるとして、ただし途中で100ms待つ

    public static class Sup implements Supplier<String>{
        private int  index;
   
        @Override
        public String get() {
            index++;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("get called");
            return ""+index;
        }
       
    }

非同期で2回実行した場合

new Thread(){
            public void run(){
                System.out.println(s.get());
            }
        }.start();
        new Thread(){
            public void run(){
               
                System.out.println(s.get());
            }
        }.start();

final Sup s=new Sup();
普通のままですと、最初のはindex++の後に、100ms待ってるあいだに2回目呼ばれてしまうので

2
2

となる。

final Supplier<String> s=Suppliers.synchronizedSupplier(new Sup())
synchronizedの場合は、getが処理し終わるまで待つので

1
2

となる。

final Supplier<String> s=Suppliers.memoize(new Sup());
memoizeは1回目を呼ぶとそれをキャッシュして2回目以降は呼ばないので(しかもsynchronizedで処理)

1
1

となる。

感想

Google App Engineでスレッドセーフにしなければいけない時とか役立ちそう。

自分で作るBuilder風なクラスは、このSupplierをimplementsにしておけば、後から、syncにしたり、メモ化(memoization)できて便利そう
メモカの場合、memoizeWithExpiration(Supplier<T> delegate, long duration, TimeUnit unit) という時間制限付きにもできそうだし


関連

http://stackoverflow.com/questions/4014589/google-guava-supplier-example
Comments