1.
FutureTask 类 的 run() 方法 来自 Runnable 的run () 方法,所以 走 run () 方法就会执行 call() 方法
原理:
源码如下:
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
public interface Future<V> {
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when {@code cancel} is called,
* this task should never run. If the task has already started,
* then the {@code mayInterruptIfRunning} parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to {@link #isDone} will
* always return {@code true}. Subsequent calls to {@link #isCancelled}
* will always return {@code true} if this method returned {@code true}.
*
* @param mayInterruptIfRunning {@code true} if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return {@code false} if the task could not be cancelled,
* typically because it has already completed normally;
* {@code true} otherwise
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns {@code true} if this task was cancelled before it completed
* normally.
*
* @return {@code true} if this task was cancelled before it completed
*/
boolean isCancelled();
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
boolean isDone();
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
V get() throws InterruptedException, ExecutionException;
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
原理:
返回 执行结果:
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
// 执行任务方法,并获取返回值
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
// 设置 线程返回值
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
流程:
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
// 调用 new FutureTask<T>(runnable, value) 构造器,生成 对象
// RunnableFuture 里 就有 了 Callable 属性
RunnableFuture<Void> ftask = newTaskFor(task, null);
//
execute(ftask);
return ftask;
}
demo:
自定义任务:
package com.example.demo.thread;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Callable;
/**
* @program: springboot_01
* @description: 程序中使用的是Callable接口,可以获取线程的返回值
* 没有返回值的 用 Runnable 接口
* @author: guoyiguang
* @create: 2021-07-11 11:01
**/
@Slf4j
public class MyTask implements Callable {
private String filename;
public MyTask(String filename) {
this.filename = filename;
}
@Override
public Object call() throws Exception {
// 要执行的任务
log.info("callable call() method thread name-----{} ,mission value----{}",Thread.currentThread().getName(),filename);
return "返回值" + filename;
}
}
测试controller:
package com.example.demo.controller;
import com.example.demo.thread.MyTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;
/**
* @program: springboot_01
* @description: 线程 控制器
* @author: guoyiguang
* @create: 2021-01-16 13:16
**/
@RestController
@RequestMapping("/thread")
@Slf4j
public class ThreadController {
/**
* 创建线程池,并发量最大为5
* LinkedBlockingDeque,表示执行任务或者放入队列
*/
ThreadPoolExecutor excutor = new ThreadPoolExecutor(5, 10, 0,
TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(),
new ThreadPoolExecutor.CallerRunsPolicy());
@PostMapping(value="a" )
@ResponseBody
public String a() throws ExecutionException, InterruptedException {
log.info("request thread name-----{}",Thread.currentThread().getName());
//存储线程的返回值
List<Future<String>> results = new LinkedList<>();
for (int i = 0; i < 10; i++) {
MyTask task = new MyTask(String.valueOf(i));
Future<String> result = excutor.submit(task);
// 收集返回值
results.add(result);
}
//输出结果
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
// 获取返回值
sb.append(results.get(i).get());
sb.append(" ");
}
return sb.toString();
}
}
执行结果:任务是不同的线程执行的
springboot 异步的应用:
先测试同步:
package com.example.demo.service;
/**
* @program: springboot_01
* @description:
* @author: guoyiguang
* @create: 2021-07-11 13:24
**/
public interface AsyncService {
long doNoReturn();
}
package com.example.demo.service.Impl;
import com.example.demo.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/**
* @program: springboot_01
* @description:
* @author: guoyiguang
* @create: 2021-07-11 13:24
**/
@Service
@Slf4j
public class AsyncServiceImp implements AsyncService {
@Override
public long doNoReturn() {
try {
long start = System.currentTimeMillis();
log.info(" thread name ------> {} ; 方法执行开始 ------> {}",Thread.currentThread().getName(),LocalDateTime.now());
// 这个方法执行需要三秒
Thread.sleep(3000);
long end = System.currentTimeMillis();
return end-start;
} catch (InterruptedException e) {
e.printStackTrace();
}
return -1L;
}
}
测试 controller:
@PostMapping(value="b" )
public long b() throws ExecutionException, InterruptedException {
log.info("request thread name-----{}",Thread.currentThread().getName());
return asyncService.doNoReturn();
}
执行时间:
异步测试:
启动类添加 异步注解:
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
//@MapperScan({"com.example.demo.mapper","com.example.demo.mapper"})
// @MapperScan 代替 @Mapper的
@MapperScan("com.example.demo.mapper")
// 开启缓存
@EnableCaching
@EnableAsync // 开启异步任务
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
}
方法上添加异步:
package com.example.demo.service.Impl;
import com.example.demo.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/**
* @program: springboot_01
* @description:
* @author: guoyiguang
* @create: 2021-07-11 13:24
**/
@Service
@Slf4j
public class AsyncServiceImp implements AsyncService {
@Async
@Override
public void doNoReturn() {
try {
long start = System.currentTimeMillis();
log.info(" thread name ------> {} ; 方法执行开始 ------> {}",Thread.currentThread().getName(),LocalDateTime.now());
// 这个方法执行需要三秒
Thread.sleep(3000);
long end = System.currentTimeMillis();
log.info(" thread name ------> {} ; 方法执行结束 ------> {}",Thread.currentThread().getName(),LocalDateTime.now());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
测试代码如下:
@PostMapping(value="b" )
public long b() throws ExecutionException, InterruptedException {
log.info("request thread name-----{}",Thread.currentThread().getName());
long start = System.currentTimeMillis();
asyncService.doNoReturn();
long end = System.currentTimeMillis();
return end - start;
}
已经返回结果: