一个程序的执行就是进程,进程中一个不可分割的最小单元就是线程,多个就是多线程。
线程分为用户线程和守护线程,守护线程就是为保护用户线程执行的线程,如gc线程。
线程:
被创建--->就绪start()--->执行run()--->休眠/等待Thread.sleep()[.interrupt()]/Object.wait()[notify(),notifyAll()]--->销毁Thread,stop()或者设置成守护线程(在start之前设置Thread.setDaemon(true))
商品详情页面因为需药加载很多数据,所以需要调用多个微服务,同步调用会造成效率低下,因此采用异步调用的方式;
线程的创建方式:1.自定义类继承Thread类 2.自定义类实现runnable接口 3.自定义类实现callable接口 4.使用线程池
前两种无法获取线程执行结果,第三种可以获得,但是无法控制服务器对线程资源的控制,容易使服务器资源耗尽。
线程池可以线程复用,定期销毁,对线程进行统一管理,但无法满足一个线程需要依赖于另一个线程的执行结果的情况
Future可以只能通过阻塞和轮询方式获取结果,阻塞与异步编程相违背,轮询会无止尽的消耗cpu资源,completableFuture是Future的实现类,可以通过回调的方式获取执行结果
ExecutorService为自定配置
CompletableFuture具有四个静态方法用来执行异步,一般使用指定Executor的作为线程池参数
static CompletableFuture<Void> runAsync(Runnable runnable) 无返回值
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 无返回值
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) 有返回值
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 有返回值
他们都有统一的返回类型CompletableFuture<T> ,无返回值的则是CompletableFuture<void>
如果有返回值且需要调用,则对该返回值调用
因为加载页面需要将所有部件都加载完成后才能返回,因此需要在return之前确认所有任务都执行完毕,才能返回数据。