使用@Async註解建立多線程很是的方便,還能夠經過配置,實現線程池。比直接使用線程池簡單太多。並且在使用上跟普通方法沒什麼區別,加上個@Async註解便可實現異步調用。java
AsyncTask.javaspring
@Component
public class AsyncTask {
private static final Logger LOG = LoggerFactory.getLogger(AsyncTask.class);
@Async
public void register(){
LOG.info("多線程開始註冊模擬");
try {
Thread.sleep(1000*1);
} catch (InterruptedException e) {
e.printStackTrace();
}
LOG.info("多線程註冊成功");
}
}
複製代碼
這裏只是作一個簡單地打印輸出,使用Log4J打印是爲了方便看到線程名springboot
AsyncTaskController.javabash
@RestController
@RequestMapping(value = "/async")
public class AsyncTaskController {
private final static Logger LOG = LoggerFactory.getLogger(AsyncTaskController.class);
@Autowired
private AsyncTask asyncTask;
@GetMapping(value = "/test")
public Object test(){
for (int i = 0; i < 10; i++) {
asyncTask.register();
}
System.out.println("主線程結束");
return "OK";
}
}
複製代碼
這裏循環建立10個線程多線程
啓用Async須要添加@EnableAsync註解app
@SpringBootApplication
@ServletComponentScan
@EnableAsync
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
複製代碼
能夠看到,主線程結束已經結束。可證證實多線程起了效果。另外經過查看線程名,能夠看到建立了10個線程去執行。異步
經過上面的結果能夠看出,直接使用@Async註解是直接建立線程去執行的。可是在實際開發中,都應該使用線程池去管理線程,節省線程開銷。async
TaskExecutorConfig.classide
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
public class TaskExecutorConfig implements AsyncConfigurer {
/**
* Set the ThreadPoolExecutor's core pool size. */ private static final int CORE_POOL_SIZE = 2; /** * Set the ThreadPoolExecutor's maximum pool size.
*/
private static final int MAX_POOL_SIZE = 2;
/**
* Set the capacity for the ThreadPoolExecutor's BlockingQueue. */ private static final int QUEUE_CAPACITY = 10; /** * 經過重寫getAsyncExecutor方法,制定默認的任務執行由該方法產生 * * 配置類實現AsyncConfigurer接口並重寫getAsyncExcutor方法,並返回一個ThreadPoolTaskExevutor * 這樣咱們就得到了一個基於線程池的TaskExecutor */ @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(CORE_POOL_SIZE); taskExecutor.setMaxPoolSize(MAX_POOL_SIZE); taskExecutor.setQueueCapacity(QUEUE_CAPACITY); taskExecutor.initialize(); return taskExecutor; } } 複製代碼
這裏設置了最大兩個線程。測試
重啓程序測試下:
結果
能夠看到只有兩個線程在執行,證實配置的線程池起做用了。