用静态常量实现一个单例模式的线程池
1.使用场景
在做项目的时候,遇到以下场景:有求解器,进行多并发求解,但又不想用redis,因此写了一个单例模型的线程池对结果进行接收,然后慢慢一个一个写入数据库中。需要注意的是,方法被调用后会立即返执行成功给主线程。这种方式属于饿汉式,可能会造成内存浪费问题。
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPool {
//创建具体的单例变量,这里你想要什么就创建什么,这里我需要线程池就创建线程池
private static final ExecutorService EXECUTOR_SERVICE= Executors.newFixedThreadPool(2);
// 将构造器私有化,这样从外部就没办法创建了
private ThreadPool(){}
//提供一个返回实例对象的公共方法,这样保证每次用的都是同一个线程池,这就是为什么他被称为单例的原因
//每次都用的都是这个
public static ExecutorService getInsatance(){
return EXECUTOR_SERVICE;
}
public static void main(String[] args) {
//测试线程效果以及查看到底是不是每次都用的是同一个线程池
for (int i = 0; i < 10; i++) {
int finalI = i;
Runnable runnable=new Runnable() {
@Override
public void run() {
try {
System.out.println("这是第"+ finalI +"个线程,线程池的内存地址为,"+ThreadPool.getInsatance().hashCode()+" 时间是:"+new Date());
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
}
};
ThreadPool.getInsatance().submit(runnable);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
2.结果
当线程数为2
这是第1个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:24 CST 2021
这是第0个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:24 CST 2021
这是第2个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:27 CST 2021
这是第3个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:27 CST 2021
这是第4个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:30 CST 2021
这是第5个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:30 CST 2021
这是第7个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:33 CST 2021
这是第6个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:33 CST 2021
这是第8个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:36 CST 2021
这是第9个线程,线程池的内存地址为,1712400905 时间是:Sun Oct 31 23:53:36 CST 2021
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
当线程数为1
这是第0个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:31 CST 2021
这是第1个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:34 CST 2021
这是第2个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:37 CST 2021
这是第3个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:40 CST 2021
这是第4个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:43 CST 2021
这是第5个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:46 CST 2021
这是第6个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:49 CST 2021
这是第7个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:52 CST 2021
这是第8个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:55 CST 2021
这是第9个线程,线程池的内存地址为,1648378190 时间是:Sun Oct 31 23:57:58 CST 2021
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3.程序执行完后主程序不会结束?idea显示在运行?
虽然我们从肉眼上看到的是程序打印完了字符,但是单例线程池没有销毁,所以是因为线程池一直在等待的原因。如果需要在线程执行完任务后,结束整个程序,使用ThreadPool.getInstance().shutdown()即可(在本例中,shutdown在for循环使用)。
推荐阅读