最近在看Guava的源码,Supplier这个小工具比较有意思,今天聊一聊。
Supplier是一个接口,里面只有一个get方法,然后Suppliers类里面有两个内部类实现了这个接口,
ExpiringMemoizingSupplier和MemoizingSupplier,它们主要是为了延迟获取在get方法中创建的对象,一个有超时时间,一个没有,其实也可以理解为将需要使用的东西做了一个懒加载和缓存的动作,MemoizingSupplier也可以用来实现单例,下边举两个例子:
1.无超时时间的实现MemoizingSupplier
public class SupplierTest {
public static void main(String[] args) throws InterruptedException {
Supplier userInfoSu = (new Supplier<User>() {
@Override
public User get() {
return new User("kobe");
}
});
Supplier memoizeserInfo = Suppliers.memoize(userInfoSu);
User first = (User) memoizeserInfo.get();
Thread.currentThread().sleep(2000);
User second = (User) memoizeserInfo.get();
if (first == second) {
System.out.println("same object");
} else {
System.out.println("diff object");
}
}
@Data
@AllArgsConstructor
static class User {
private String name;
}
}
输出:same object
可以看到,两次返回的对象是同一个
2.有超时时间的实现ExpiringMemoizingSupplier
public class SupplierTest {
public static void main(String[] args) throws InterruptedException {
Supplier userInfoSu = (new Supplier<User>() {
@Override
public User get() {
return new User("kobe");
}
});
Supplier expirationUserInfo = Suppliers.memoizeWithExpiration(userInfoSu, 2000, MILLISECONDS);
User first = (User) expirationUserInfo.get();
Thread.currentThread().sleep(1000);
User second = (User) expirationUserInfo.get();
if (first == second) {
System.out.println("same object");
} else {
System.out.println("diff object");
}
Thread.currentThread().sleep(3000);
User third = (User) expirationUserInfo.get();
if (second == third) {
System.out.println("same object");
} else {
System.out.println("diff object");
}
}
@Data
@AllArgsConstructor
static class User {
private String name;
}
}
输出:
same object
diff object
可以看到,在超时时间内,返回的对象是同一个,过了超时时间,返回的是两个对象
总结:
1.可以对一些大的对象,在需要的时候进行懒加载
2.可以当做缓存或者单例模式来使用