ThreadFactoryBuilder
com.google.common.util.concurrent.ThreadFactoryBuilder
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ThreadFactoryBuilderTest {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadFactoryBuilder().setNameFormat("-sh-file-transport-%d").build());
threadPoolExecutor.execute(() -> {
try {
TimeUnit.SECONDS.sleep(10);
log.info("end " + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
SettableFuture
com.google.common.util.concurrent.SettableFuture
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@Slf4j
public class SettableFutureTest {
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadFactoryBuilder().setNameFormat("-sh-file-transport-%d").build());
/**
* 适用场景
* 我们在做网络通信时,假设一般请求-响应都是在3秒以内拿到结果.
* 但有的时候遇到网络动荡、硬件性能问题时会导致超时,
* 5秒,10秒甚至更多。但是我们希望超过5秒的请求我们就认为失败,
* 这个时候SettableFuture就可以出场了,代码优雅,又能解决实际问题。
*/
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
SettableFuture settableFuture = SettableFuture.create();
Future<String> submit = threadPoolExecutor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(10);
log.info("end " + Thread.currentThread().getName());
String result = "张三";
settableFuture.set(result);
return result;
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
});
log.info((String) settableFuture.get(5, TimeUnit.SECONDS));
}
}
ListenableFuture
com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
public class ListenableFutureTest {
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadFactoryBuilder().setNameFormat("-sh-file-transport-%d").build());
public static void main(String[] args) {
ListeningExecutorService listeningExecutor = MoreExecutors.listeningDecorator(threadPoolExecutor);
//执行主方法的调用
final ListenableFuture<String> future = listeningExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
log.info("listeningExecutor --- start");
TimeUnit.SECONDS.sleep(2);
log.info("listeningExecutor --- end");
return "hello_world";
}
});
//添加执行完成后的监听
future.addListener(new Runnable() {
@Override
public void run() {
try {
System.out.println("future addListener 收到通知..." + future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}, listeningExecutor);
//添加执行完成后的回调
Futures.addCallback(future, new FutureCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("future addCallback onSuccess: " + result);
}
@Override
public void onFailure(Throwable t) {
System.out.println("future addCallback onFailure: ");
t.printStackTrace();
}
}, listeningExecutor);
}
}
AsyncFunction
com.google.common.util.concurrent.AsyncFunction
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
public class AsyncFunctionTest implements AsyncFunction<Long,String> {
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadFactoryBuilder().setNameFormat("-sh-file-transport-%d").build());
private ConcurrentMap<Long,String> map = Maps.newConcurrentMap();
private ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(threadPoolExecutor);;
@Override
public ListenableFuture<String> apply(final Long input) {
if (map.containsKey(input)) {
SettableFuture<String> listenableFuture = SettableFuture.create();
listenableFuture.set(map.get(input));
return listenableFuture;
} else {
return listeningExecutorService.submit(new Callable<String>() {
@Override
public String call() {
String retrieved = String.valueOf(input);
map.putIfAbsent(input, retrieved);
return retrieved;
}
});
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ListenableFuture<String> apply = new AsyncFunctionTest().apply(100L);
String s = apply.get();
log.info(s);
}
}
Immediate
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@Slf4j
public class ImmediateTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//immediateFuture 表示该方法立即返回
ListenableFuture<String> future = Futures.immediateFuture("immediateFuture");
//实现和immediateFuture差不多,提供了两个checkedGet()方法
future = Futures.immediateCheckedFuture("immediateCheckedFuture");
//构造一个cancel的future,当调用get()方法时 立即抛出异常
future = Futures.immediateCancelledFuture();
//调用get()方法和checkedGet()抛出异常
future = Futures.immediateFailedCheckedFuture(new NullPointerException("immediateFailedCheckedFuture"));
//当调用get()方法时,抛出异常
future = Futures.immediateFailedFuture(new NullPointerException("immediateFailedFuture"));
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Integer> futures = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
Thread.sleep(2000);
System.out.println("future task done......");
return 1;
}
});
//因为futures.get()返回的是Integer,如果想在get()方法返回之后,利用其返回值做一些其他操作.就可以使用
//transform()方法,手动转换为对其类型结果的获取:
ListenableFuture<Boolean> transform = Futures.transformAsync(futures, new AsyncFunction<Integer, Boolean>() {
public ListenableFuture<Boolean> apply(Integer integer) throws Exception {
return integer > 0 ? Futures.immediateFuture(Boolean.TRUE) : Futures.immediateFuture(Boolean.FALSE);
}
}, executor);
log.info(String.valueOf(transform.get()));
//使用JdkFutureAdapters来完成JDK Future到ListenableFuture的转换
Future<Integer> jdkFuture = Executors.newSingleThreadExecutor().submit(() -> 1);
ListenableFuture<Integer> listenFuture = JdkFutureAdapters.listenInPoolThread(jdkFuture);
}
}