什么是线程池
线程池:用于管理线程对象的池子。
为什么使用线程池
一个线程大约占用1M内存
1.解决频繁创建线程和销毁线程消耗的性能。
2.解决大量创建线程而导致的内存泄漏问题。
如何创建线程池
java中提供了两种方式:
第一种:通过工具类完成线程池的创建。[Executors]。语法简单。但阿里巴巴不建议使用。
第二种:通过线程池类:ThreadPoolExcutor类。语法复杂,但是阿里巴巴建议使用。灵活线程的根接口:Executors。里面只有一个方法:execute
子接口:ExecutorService。
第一种方案Executors:
1.固定大小的线程池对象:newFixedThreadPool
2.单一线程池:newSingleThreadExecutor
3.可变线程池:newCachedThreadPool
4.延迟线程池:newScheduledThreadPool
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) {
//创建一个固定大小的线程池,返回类型为ExecutorService
ExecutorService executorService=Executors.newFixedThreadPool(5);
//创建单一线程池(池子里只有一个线程对象)适合任务执行的
ExecutorService executorService1=Executors.newSingleThreadExecutor();
//创建可变线程池(池子中线程的数量会随着任务大小而改变)
ExecutorService executorService2=Executors.newSingleThreadExecutor();
//延迟线程池(指定时间后执行)
ScheduledExecutorService executorService3=Executors.newScheduledThreadPool(5);
//执行线程任务 Runnable Callable Integer MAX()整数最大值
for (int i = 0; i < 10; i++) {
//必须传递Runnable对象。[1]自己创建一个类实现Runnable接口[2]匿名内部类对象[3]lambda表达式:前提接口必须为函数式接口
executorService.execute(new My());
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"......");
}
});
}
//10秒后执行代码块
executorService3.schedule(()->{
System.out.println(Thread.currentThread().getName()+"********");
},10, TimeUnit.SECONDS);
executorService3.scheduleAtFixedRate(()->{
System.out.println(Thread.currentThread().getName());
},5,2,TimeUnit.SECONDS);
//关闭线程池
executorService.shutdown();
executorService1.shutdown();
executorService2.shutdown();
executorService3.shutdown();
}
}
class My implements Runnable {
@Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println("!!!***???");
}
}
}
第二种方式ThreadPoolExecutor
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test1 {
public static void main(String[] args) {
//核心参数的意思
/*
* int corePoolSize,线程数的个数 2
* int maximumPoolSize,最大线程数数量 5
* long keepAliveTime,非核心线程允许空闲时间
* TimeUnit unit,时间单位
* BlockingQueue<Runnable> workQueue 阻塞队列中 3
*/
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue(5);
ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(2,6,10, TimeUnit.SECONDS,workQueue);
for (int i = 0; i < 11; i++) {
poolExecutor.submit(()->{
System.out.println(Thread.currentThread().getName()+"^*^");
});
}
poolExecutor.shutdown();
}
}
execute和submit方法区别
1.这两个方法都是用来执行线程任务,但是execute属于Executor类中的方法,而submit属于ExecutorService接口中的方法。
2.submit可以执行runnable和callable类型任务,而execute只能执行Runnable类型的任务。
3.submit执行完任务后有返回结果。