Guava笔记之Supplier和Suppliers的使用

Supplier封装了获取值的功能,可以实现多种不同的获取值的方式,创建Supplier可以使用Suppliers类的静态方法来实现,该方法提供了多种获取值的方式,具体为:
在这里插入图片描述

一、Supplier接口

该接口提供了get方法用于获取值,注意其中get方法并不能传递参数信息,所以如果需要传递参数信息的话则不适用该接口。

public interface Supplier<T> extends java.util.function.Supplier<T> {
  T get();
}

二、实例化Supplier的方式

1、Suppliers.ofInstance(T instance) 方法

该种调用方式为最简单的实现方式,在调用get方法时会直接将传递的instance返回。

public static <T> Supplier<T> ofInstance(@Nullable T instance) {
   return new SupplierOfInstance<T>(instance);
 }
 
private static class SupplierOfInstance<T> implements Supplier<T>, Serializable {
    final @Nullable T instance;
    SupplierOfInstance(@Nullable T instance) {
      this.instance = instance;
    }
    @Override
    public T get() {
      return instance;
    }
  }

2、Suppliers.memoize(Supplier delegate)方法

该方法返回的Supplier会通过传递的delegate参数来获取值并缓存,之后再次调用get方法时会直接将缓存中的值返回。

public static <T> Supplier<T> memoize(Supplier<T> delegate) {
   if (delegate instanceof NonSerializableMemoizingSupplier
       || delegate instanceof MemoizingSupplier) {
     return delegate;
   }
   return delegate instanceof Serializable
       ? new MemoizingSupplier<T>(delegate)
       : new NonSerializableMemoizingSupplier<T>(delegate);
 }
 // 具体的Supplier类
 static class NonSerializableMemoizingSupplier<T> implements Supplier<T> {
    volatile Supplier<T> delegate; // 代理类
    volatile boolean initialized; //记录是否已经获取过值了 

    @Nullable T value;   //缓存的结果信息

    NonSerializableMemoizingSupplier(Supplier<T> delegate) {
      this.delegate = checkNotNull(delegate);
    }

    @Override
    public T get() {
      // 根据initialized实现的双重检查
      if (!initialized) {
        synchronized (this) {
          if (!initialized) {
            T t = delegate.get(); // 只会在初始化的时候调用delegate的get方法一次
            value = t;
            initialized = true;
            delegate = null; // 释放delegate 因为后面用不到了
            return t;
          }
        }
      }
      return value;
    }
}

3、Suppliers.memoizeWithExpiration(Supplier delegate, long duration, TimeUnit unit)方法

该方法会根据指定的durationunit每隔指定时间调用delegateget方法一次,相当于是定时刷新结果值。

public static <T> Supplier<T> memoizeWithExpiration(
      Supplier<T> delegate, long duration, TimeUnit unit) {
    return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
}

// 具体的ExpiringMemoizingSupplier实现
static class ExpiringMemoizingSupplier<T> implements Supplier<T>, Serializable {
    final Supplier<T> delegate; // 具体获取结果的代理类
    final long durationNanos; // 刷新结果间隔的纳秒值
    transient volatile @Nullable T value; // 缓存的结果信息
    transient volatile long expirationNanos; // 0表示还没有初始化 否则表示下一次过期的时间
    
    ExpiringMemoizingSupplier(Supplier<T> delegate, long duration, TimeUnit unit) {
      this.delegate = checkNotNull(delegate);
      this.durationNanos = unit.toNanos(duration);
      checkArgument(duration > 0, "duration (%s %s) must be > 0", duration, unit);
    }

    @Override
    public T get() {
      long nanos = expirationNanos;
      long now = Platform.systemNanoTime();
      if (nanos == 0 || now - nanos >= 0) {
        synchronized (this) {
          if (nanos == expirationNanos) {      // 双重检查防止重复加载
            T t = delegate.get();
            value = t;
            nanos = now + durationNanos;
            expirationNanos = (nanos == 0) ? 1 : nanos;
            return t;
          }
        }
      }
      return value;
    }
}

4、Suppliers.synchronizedSupplier(Supplier delegate)方法

该方法会以synchronized的方式实现线程安全的调用,并且每次都会执行delegate的get方法来获取值。

public static <T> Supplier<T> synchronizedSupplier(Supplier<T> delegate) {
    return new ThreadSafeSupplier<T>(delegate);
}
private static class ThreadSafeSupplier<T> implements Supplier<T>, Serializable {
    final Supplier<T> delegate;

    ThreadSafeSupplier(Supplier<T> delegate) {
      this.delegate = checkNotNull(delegate);
    }

    @Override
    public T get() {
      synchronized (delegate) { // 基于synchronized实现的线程安全
        return delegate.get(); // 每次都会调用get方法来获取值
      }
    }
}

5、Suppliers.compose(Function<? super F, T> function, Supplier delegate)方法

每次获取值都会调用delegateget方法,并且使用传递的function对返回值进行处理。

public static <F, T> Supplier<T> compose(Function<? super F, T> function, Supplier<F> supplier) {
    return new SupplierComposition<>(function, supplier);
}

private static class SupplierComposition<F, T> implements Supplier<T>, Serializable {
    final Function<? super F, T> function;
    final Supplier<F> delegate;

    SupplierComposition(Function<? super F, T> function, Supplier<F> delegate) {
      this.function = checkNotNull(function);
      this.delegate= checkNotNull(delegate);
    }

    @Override
    public T get() {
      return function.apply(delegate.get()); // 每次都会执行delegate的get方法并且使用function进行处理
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值