在Java中创建多线程,一般有三种方式:
- 通过继承Thread类
- 通过实现Runable接口
- 通过Callable接口
第一种方法最为简单,直接创建线程对象,再启动即可,但由于Java是单继承的,所以继承了Thread之后,就不能再继承其他类了。我最喜欢的是第二种方式,只要实现Runable接口,然后放到Thread对象中,启动线程,即可,也不会很难。
但是,有时候,我们有一些特殊的需求,我们要获得线程执行完之后的结果。如果,用第一、第二种是不能实线带返回值的。只能用第三种方法。
下面就来简单地记录一下:
- 创建线程执行体
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
//线程执行体
System.out.println("Test");
//返回值
return "Test";
}
};
Callable是不能直接运行的,必须依附于Thread对象,但是Thread并没有提供直接运行Callable的方法。不过,Java也给我们提供了,把Callable转为Runable的”方法”。
//创建FutureTask
FutureTask<String> futureTask = new FutureTask<>(callable);
FutureTask是一个既实现了Future,也实现了Runable接口的实现类, Future是提供了处理返回值的方法。
也就是说,futureTask 是一个Runable,所以,启动这个线程,跟启动实现Runable的线程一下。
//创建线程
Thread thread = new Thread(future);
//启动线程
thread.start();
线程已经启动。但是我们说好的返回值呢?
获取线程的返回值,我们是通过Future的方法来实现的,所以,我们获取的线程的返回值,就必须使用futureTask来获取返回结果。
try {
//阻塞等待线程返回
//返回值类型为Callable定义的类型
String result = future.get();
//这种是不阻塞,等待5秒钟
//future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
结论:
多线程的基本使用,并不难,难的是线程安全、同步问题。这里记录一下,基本操作,之后再深入了解。