# thread-lock **Repository Path**: M-N-A/thread-lock ## Basic Information - **Project Name**: thread-lock - **Description**: thread-lock study - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-09-08 - **Last Updated**: 2023-11-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # java spi机制简介 java的spi是一种服务发现机制,很多文章中介绍spi机制的时候都会说一句类似spring框架的IOC容器。SPI源语的全称是“Service Provider Interface”,即“服务提供者的接口”,该接口的使用者是服务提供方,谁提供服务谁使用spi接口。该机制的经典使用案例是jdbc框架,一个优秀的基于此框架扩展的是dubbo框架。 ## 一:什么是SPI机制? 1. SPI 全称:Service Provider Interface 2. 字面意思:服务提供者的接口 3. 我们来拆开分析一下,首先它是一个接口,然后是提供服务调用者使用的。 ### 为什们要使用spi: 在面向对象编程中,基于开闭原则和解耦的需要,一般建议用接口进行模块之间通信编程,通常情况下调用方模块是不会感知到被调用方模块的内部具体实现。为了实现在模块装配的时候不用在程序里面动态指明,这就需要一种服务发现机制。Java SPI 就是提供了这样一个机制:为某个接口寻找服务实现的机制。这有点类似 IoC 的思想,将装配的控制权移交到了程序之外。 ### 重新理解spi机制: 1. SPI是专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口。 2. SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服务实现者解耦,能够提升程序的扩展性、可维护性。修改或者替换服务实现并不需要修改调用方。 ## 二:SPI机制的广泛应用? ### 1. SPI机制在JDBC DriverManager中的应用 在JDBC4.0之前,我们开发有连接数据库的时候,通常会用Class.forName("com.mysql.jdbc.Driver") 这句先加载数据库相关的驱动,然后再进行获取连接等的操作。而JDBC4.0之后不需要用Class.forName("com.mysql.jdbc.Driver") 来加载驱动,直接获取连接就可以了,现在这种方式就是使用了Java的SPI扩展机制来实现。 ### 2. SPI机制在Common-Logging中的实现 ## 三:带着问题深入理解SPI机制? 1. API依赖的接口位于实现者的包中,概念上更接近于实现方,组织上存在于实现者的包中,实现和接口同时存在在实现者的包中 2. SPI依赖的接口在调用方的包中,概念上更接近于调用方,组织上位于调用者的包中,实现逻辑在单独的包中,实现可插拔。 ## SPI机制的缺陷 1. 不能按需加载,需要遍历所有的实现,并实例化,然后在循环中才能找到我们需要的实现。如果不想用某些实现类,或者某些类实例化很耗时,它也被载入并实例化了,这就造成了浪费。 2. 获取某个实现类的方式不够灵活,只能通过 Iterator 形式获取,不能根据某个参数来获取对应的实现类。(Spring 的BeanFactory,ApplicationContext 就要高级一些了。) 3. 多个并发多线程使用 ServiceLoader 类的实例是不安全的。 # Future 和 FutureTask 的区别 ## Future提供了三种功能 1. 判断任务是否完成 (调用`isDone()`方法); 2. 能够中断任务 (调用`cancel(true)`方法); 3. 能够获取任务执行结果 (调用 `get()` 方法); ## FutureTask * `FutureTask` 是 `Future` 的实现类,`FutureTask` 对象可以对实现 `Callable` 和 `Runnable` 的对象进行包装,由于 `FutureTask` 也实现了 `Runnable` 接口,所以它可以提交给 `Executor` 来执行; * `FutureTask` 可取消的异步任务,提供 `Future` 的基础实现,并实现了 `Runnable` 接口,`FutureTask` 包含了取消与启动计算的方法,查询计算是否完成以及检索计算结果的方法,只有在计算完成才能检索到结果,调用 `get()` 方法时,如果任务还没有完成,将会阻塞调用线程至到任务完成。 ## CompletableFutureTask ### 解释:实现了 `Future` 接口和 `CompletionStage` 接口。其中 `CompletionStage` 中包含多种处理方法用于异步计算、异常处理和计算结合等等 * CompletableFuture 可调用 complete 方法手动完成;