需求:将三张表的查询结果 定时保存到另一张表中
可以采用串行执行 也可以用并行执行,提高查询速度此处用并行的方式,充分利用cup资源,通过Callable接口实现多线程,实现Callable重写call方法;
实现Callable和实现Runnable类似,但是功能更强大,具体表现在:
a.可以在任务结束后提供一个返回值,Runnable不行;
b.call方法可以抛出异常,Runnable的run方法不行;
c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值);
a.可以在任务结束后提供一个返回值,Runnable不行;
b.call方法可以抛出异常,Runnable的run方法不行;
c.可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的结果,得到返回值,(fulture.get(),调用后会阻塞,直到获取到返回值);
1、Callable接口介绍:
(1)java.util.concurrent.Callable是一个泛型接口,只有一个call()方法;
(2)call()方法抛出异常Exception异常,且返回一个指定的泛型类对象;
2、Callable接口实现多线程的应用场景
(1)当父线程想要获取子线程的运行结果时;
3、使用Callable接口实现多线程的步骤
(1)第一步:创建Callable子类的实例化对象;
(2)第二步:创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中(注意:FutureTask实现了Runnable接口和Future接口);
(3)第三步:实例化Thread对象,并在构造方法中传入FurureTask对象;
(4)第四步:启动线程;
(1)java.util.concurrent.Callable是一个泛型接口,只有一个call()方法;
(2)call()方法抛出异常Exception异常,且返回一个指定的泛型类对象;
2、Callable接口实现多线程的应用场景
(1)当父线程想要获取子线程的运行结果时;
3、使用Callable接口实现多线程的步骤
(1)第一步:创建Callable子类的实例化对象;
(2)第二步:创建FutureTask对象,并将Callable对象传入FutureTask的构造方法中(注意:FutureTask实现了Runnable接口和Future接口);
(3)第三步:实例化Thread对象,并在构造方法中传入FurureTask对象;
(4)第四步:启动线程;
@Component
public class TaskDemo {
@Autowired
AgeMapper ageMapper;
@Autowired
NameMapper nameMapper;
@Autowired
SexMapper sexMapper;
@Autowired
PropertyMapper propertyMapper;
@Scheduled(cron = "0 38 16 * * ?")//每天下午16:38 执行
//@Scheduled(cron = "0 0/2 0 * * ?")//每两分钟执行一次
public void test() throws ExecutionException, InterruptedException {
//创建线程池
Property property = new Property();
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
Future agefuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectAgeById", new Object[]{"1"}));
Future namefuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectNameById", new Object[]{"1"}));
Future sexfuture = poolExecutor.submit(new SelectObjectThread<>(this, "selectSexById", new Object[]{"1"}));
//用do while 保证三个线程都执行完毕
do {
System.out.println("任务正在执行中。。。。。");
} while (!agefuture.isDone() && !namefuture.isDone() && !sexfuture.isDone());
Age age = (Age) agefuture.get();
Name name = (Name) namefuture.get();
Sex sex = (Sex) sexfuture.get();
property.setAge(age.getAge());
property.setName(name.getName());
property.setSex(sex.getSex());
System.out.println("开始写入数据");
propertyMapper.insert(property);
System.out.println("写入数据完毕");
poolExecutor.shutdown();
}
public Age selectAgeById(String id) {
return ageMapper.selectById("1");
}
public Name selectNameById(String id) {
return nameMapper.selectById("1");
}
public Sex selectSexById(String id) {
return sexMapper.selectById("1");
}
class SelectObjectThread<T> implements Callable<T> {
private Object object;
private String methodName;
private Object[] objects;
public SelectObjectThread(Object object, String methodName, Object[] objects) {
this.object = object;
this.methodName = methodName;
this.objects = objects;
}
@Override
public T call() throws Exception {
long start = System.currentTimeMillis();
Method method = object.getClass().getMethod(methodName, String.class);// String.class调用方法的参数类型
/* String name = method.getName();
if (name.equals("selectAgeById")){
Thread.sleep(20000);
}*/
T t = (T) method.invoke(object, objects);
//System.out.println(t);
long end = System.currentTimeMillis();
System.out.println("执行" + methodName + "查询用时:" + (end - start));
return t;
}
}
}
@SpringBootApplication
@MapperScan({"com.yckj.mapper"})
@EnableScheduling
public class TimerApplication {
public static void main(String[] args) {
SpringApplication.run(TimerApplication.class, args);
}
}

