Callable 接口与Runnable接口类似可实现多线程的创建,但与Runnable不同的是,其线程方法call()有返回值并可抛出异常(Runnable 不会返回结果,并且无法抛出经过检查的异常)。另外Callable创建多线程依赖于线程池。
通过API查询,可以看到,Callable<V>是带泛型的,其泛型就是call方法返回值类型。
以下通过创建商品“秒杀”多线程FlashSale,实例讲解Callable 实现多线程的步骤:
1. 创建线程类FlashSale,实现Callable接口,重写call方法。
2.创建FlashSale线程实例binge,craze。
3.创建线程池对象实例shoppingPool
4.通过线程池实例shoppingPool的submit方法执行binge,craze。
package net.mosang.callabledemo;
import java.util.concurrent.Callable;
/**
* FlashSale线程类
* @author Heiry
* 重写不带任何参数的 call方法,返回String类型的抢购结果提示
*/
public class FlashSale implements Callable<String>{
private String goodsName;
@Override
public String call() throws Exception {
if(goodsName.equals("Mac电脑")) {
return "抢到了苹果电脑";
}else if (goodsName.equals("Mi手机")) {
return "抢到了小米手机";
}
else {
return "什么也没抢到";
}
}
public FlashSale(String goodsName) {
super();
this.goodsName = goodsName;
}
}
package net.mosang.callabledemo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
*
* @author Heiry
*
*/
public class Shopping {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FlashSale binge = new FlashSale("Mac电脑"); //创建线程实例binge
FlashSale craze = new FlashSale("Mi手机");//创建线程实例craze
ExecutorService shoppingPool = Executors.newFixedThreadPool(2);
Future<String> s1 = shoppingPool.submit(binge);
Future<String> s2 = shoppingPool.submit(craze);
System.out.println(s1.get());
System.out.println(s2.get());
}
}
输出结果
抢到了苹果电脑 抢到了小米手机
可见,相比继承Thread与实现Runable接口方式实现多线程,Callable更方便地得到多线程的返回值并进行异常处理。另外,Callable依赖于线程池,通过此方式创建多线程,步骤繁琐,更适合处理高并发。


适配器模式包含以下主要角色。
1. 已经存在的、具备完备功能的类 Adaptee(适配者)。
2. 当前系统业务所期待的接口(Target),但与现Adaptee不兼容,它可以是抽象类或接口。
3. 适配器类(Adapter)。通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
实例:
现有一个两孔插座,能对外提供220v稳定电压,但现业务需要,需要提供三孔插座,同样输出220v稳定电压,这就需要一个适配器来进行转换。

代码结构及详细:
package net.mosang.adapter;
public interface ThreeSocket {
public void threeSocket220v();//期望三孔输出220v电压的插线板
}
package net.mosang.adapter;
public class TwoSocket {
public void twoSocket220v() {//现有两孔可输出220v电压的插线板
System.out.println("220v电压持续输出中。。。。。");
}
}
package net.mosang.adapter;
public class Adaptor implements ThreeSocket {
private TwoSocket two;
@Override
public void threeSocket220v() { //对外提供了三孔220v电压功能线板
two.twoSocket220v();//实际依然是经过两孔输出
}
public TwoSocket getTwo() {
return two;
}
public void setTwo(TwoSocket two) {
this.two = two;
}
public Adaptor(TwoSocket two) {
super();
this.two = two;
}
}
package net.mosang.adapter;
public class Client {
public static void main(String[] args) {
TwoSocket two = new TwoSocket();
Adaptor adaptor = new Adaptor(two);
adaptor.threeSocket220v(); // 输出"220v电压持续输出中。。。。。"
}
}
UML关系图:
