Java 多线程与并发编程
首先讲讲使用线程池与单独创建线程的区别:
单独创建线程:
缺点:a. 每次new Thread新建对象,性能差。
b. 线程缺乏统一管理,可能无限制的新建线程,相互之间竞争,可能占用过多的系统资源导致死机。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
优点:a. 简单,灵活
创建线程池:
缺点:a. 创建比较繁琐
b. 可能因为设置的问题导致死锁,线程泄露等
优点:a. 重用存在的线程, 减少对象创建、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多的资源竞争,避免堵塞。
c. 提供定时执行、定期执行、单线程、并发数控制、制定队列大小、失败策略等功能,可以根据具体项目自定义创建不同功能的线程池。
以上为目前对线程池与新建线程的粗浅理解,以下简单的pull一下自己写的demo,以便后期可以回顾,加深理解。
线程池:
taskExecutor.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Configuration @EnableAsync public class taskExecutor { @Autowired TaskThreadPoolConfig taskThreadPoolConfig; @Bean("ThreadPoolExecutor") public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(taskThreadPoolConfig.getCoreSize()); executor.setMaxPoolSize(taskThreadPoolConfig.getMaxSize()); executor.setQueueCapacity(taskThreadPoolConfig.getQueueCapacity()); executor.setKeepAliveSeconds(taskThreadPoolConfig.getKeepAlive()); executor.setThreadNamePrefix("task-executor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } }
Controller.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Slf4j @RestController @RequestMapping("/thead") public class Controller { @Autowired private AsyncService asyncService; @GetMapping("/test/taskPool") public String taskPool() { asyncService.executeAsync(15); return "success"; } @GetMapping("/test/thread") public String thread() { asyncService.executeThread(15); return "success"; } @GetMapping("/test/runnable") public String runnable() { asyncService.executeRunnable(15); return "success"; } @GetMapping("/test/runnableWithOutNew") public String runnableWithOutNew() { asyncService.executeRunnableWithOutNew(15); return "success"; } }
AsyncService.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public interface AsyncService { void executeAsync(Integer id); void executeThread(Integer id); void executeRunnable(Integer id); void executeRunnableWithOutNew(Integer id); }
AsyncServiceImpl.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Slf4j @Service public class AsyncServiceImpl implements AsyncService { /** * 线程池 * @param id */ @Override @Async("ThreadPoolExecutor") public void executeAsync(Integer id) { log.info("start executeAsync id : " + id); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("end executeAsync id : " + id); } /** * 单独新建线程 * @param id */ @Override public void executeThread(Integer id) { MyThread myThread = new MyThread(id); myThread.start(); } class MyThread extends Thread { private Integer id; public MyThread(Integer id) { this.id = id; } public void run() { log.info("start executeAsync id : " + id); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("end executeAsync id : " + id); } } /** * 单独新建线程 * @param id */ @Override public void executeRunnable(Integer id) { MyRunnable myRunnable = new MyRunnable(id); Thread t = new Thread(myRunnable); t.start(); } class MyRunnable implements Runnable { private Integer id; public MyRunnable(Integer id) { this.id = id; } @Override public void run() { log.info("start executeAsync id : " + id); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("end executeAsync id : " + id); } } /** * 单独新建线程 * @param id */ @Override public void executeRunnableWithOutNew(Integer id) { Runnable runnable = new Runnable() { @Override public void run() { log.info("start executeAsync id : " + id); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("end executeAsync id : " + id); } }; Thread t = new Thread(runnable); t.start(); } }