永线程池就不会内存泄漏,否则一直创建线程了(如果业务量大很危险了,中断报警…?)
【@EnableAsync实现异步任务,简单用法】-CSDN博客
两种方法:
1、在启动类上加@EnableAsync注解(@Async默认的线程池是SimpleAsyncTaskExecutor)
1.SimpleAsyncTaskExecutor,不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程,没有最大线程数设置。并发大的时候会产生严重的性能问题。
创建新线程、无限、不重用。这和我们印象中的的线程池不一样,可以说是相悖的,完美躲过线程池优势。
线程池的优势:
降低创建线程和销毁线程的性能开销。
提高响应速度,当有新任务需要执行是不需要等待线程创建就可以立马执行。
合理的设置线程池大小可以避免因为线程数超过硬件资源瓶颈带来的问题。
2.在Java中创建线程并不便宜,线程对象占用大量内存,在大型应用程序中,分配和取消分配许多线程对象会产生大量内存管理开销。
原文链接:Spring默认线程池SimpleAsyncTaskExecutor-CSDN博客
2、在需要实现异步的方法上加@Async(如果加在类上,那么类中全部方法都实现异步,建议加载具体需要实现异步的方法上)
二、使用自定义线程池(推荐)
1、新建一个自定义线程池配置类@Configuration(配合bean)
2、方法上用到@Async注解需要指定线程池的Bean名字(如果配置了一个线程池,直接用@Async就会用自定义线程池执行,如果有多个线程池配置,需要指定自定义线程池的Bean名字,否则@Async会使用默认的线程池SimpleAsyncTaskExecutor处理)
SpringBoot开启异步多线程_springboot 异步线程-CSDN博客
这个就是推荐用法了
失效原因之一(要注意):
在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解失效的原因和解决方法_java async调用了两次-CSDN博客
了解了失效的原因,解决的方法就简单了(两种):
1.把这两个方法分开到不同的类中;
2.把注解加到类名上面(这个类所有方法may都有注解的效果了..);
java常用多线程(如果不用上面注解,一般都用线程池&实现Callable
接口重写call()方法实现多线程):
java 多线程实现的三种方式区别_java 多线程区别-CSDN博客
如下就是实战用的:
import java.util.concurrent.Callable;public class MyCall implements Callable<Long> {private int num;private String threadName;private long result;public MyCall(int num, String threadName) {this.threadName = threadName;this.num = num;}public Long call() throws Exception {for (int i = 0; i < num; i++) {result += i;}return result;}
}// 线程池方式测试import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class ThreadPool {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCall myCall_1 = new MyCall(10, "call_1");MyCall myCall_2 = new MyCall(10000, "call_2");ExecutorService service = Executors.newFixedThreadPool(5);Future<Long> f1 = service.submit(myCall_1);Future<Long> f2 = service.submit(myCall_2);System.out.println(f1.get()); // 获取返回System.out.println(f2.get()); // 获取返回service.shutdown();}
}
java小语法:
package thread;:这行代码声明了当前文件中的类属于 thread 包。包的作用是将相关的类和接口组织在一起,便于管理和避免命名冲突。但是实际不属于这个包,没必要硬来
线程快慢输出问题:(笔试题)
java多线程顺序输出_java: 第1关:顺序输出-CSDN博客
这个文章用到了join知识:java中join方法的理解和说明_5.join方法内部使用了()。(2分)aisaliveb.isdaemoncisactiv-CSDN博客
java 中的 join() 方法在多线程中会涉及到,这个方法最初理解起来可能有点抽象,用一两次大概就懂了。简单说就是当前线程等待调用join方法的线程结束才能继续往下执行。
这相当于同时启动
-------------------
Java子线程和主线程交替输出(一个简单的实例)_java主线程中start另一个线程,是继续主线程结果输出完马上输出另一个线程-CSDN博客
线程同步知识(见到在学了):
java 中轻量级volatile同步字段解释_java 同步字段-CSDN博客
java 的 synchronized 同步方法使用场景举例解读_java 全局缓存采用synchronized示例-CSDN博客