java多线程实现方式:
1、继承Thread类。
2、实现Runnable接口,无返回结果。
3、实现Callable接口通过FutureTask包装器来创建Thread线程,Callable有返回结果。
package com.alex.callable;
import java.util.concurrent.*;
/**
* @author: alex
* @Date: 2019/3/20
* @Description: 演示Callable和FutureTask的配合使用
* 场景描述:
* 查询账户信息和账户金额,如果串行执行,那么就需要先执行查询用户信息,再执行查询账户金额,耗时就是两个查询的总和。
* 使用Callable和FutureTask,变为并行执行,在执行查询用户信息的同时,也在执行查询账户金额,那么耗时就是两个查询中最大的耗时。
* 注意:FutureTask的get方法是线程阻塞的,必须要等待线程都执行完成后,才能获取到结果。
*/
public class QueryAccountDemo {
public static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
/**
* 查询用户信息
*/
static class QueryAccountInfo implements Callable<String> {
private String name;
public QueryAccountInfo(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
System.out.println("获取账户信息...");
Thread.sleep(5000);
return name;
}
}
/**
* 查询账户金额信息
*/
static class QueryAccountMoney implements Callable<Integer> {
private int money = 0;
public QueryAccountMoney(int money) {
this.money = money;
}
@Override
public Integer call() throws Exception {
System.out.println("获取账户金额信息...");
Thread.sleep(4000);
return money;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//使用FutureTask包装Callable的实现类,因为FutureTask实现了Runnable接口。
FutureTask<String> futureTask1 = new FutureTask<>(new QueryAccountInfo("Alex"));
FutureTask<Integer> futureTask2 = new FutureTask<>(new QueryAccountMoney(10));
// new Thread(futureTask1).start();
// new Thread(futureTask2).start();
fixedThreadPool.submit(futureTask1);
fixedThreadPool.submit(futureTask2);
Thread.sleep(1000);
if (!futureTask1.isDone()) {
System.out.println("还没有获取用户信息...");
}
if (!futureTask2.isDone()) {
System.out.println("还没有获取用户金额信息...");
}
System.out.println("用户名:" + futureTask1.get() + ",金额:" + futureTask2.get());
fixedThreadPool.shutdownNow(); //执行完成,停止所有线程
}
}
运行结果:
获取账户信息...
获取账户金额信息...
还没有获取用户信息...
还没有获取用户金额信息...
用户名:Alex,金额:10