若米知识 > 百科 > 静态方法与单例—静态内部类方法构建单例模式创建ThreadPoolExecutor线程池

静态方法与单例—静态内部类方法构建单例模式创建ThreadPoolExecutor线程池

导读静态内部类方法构建单例模式创建ThreadPoolExecutor线程池最佳答案之前写过一篇 java线程池ThreadPoolExecutor使用无界队列LinkedBlockingQueue实现多线程 简单记录了下ThreadPoolExecutor使用无界队列...

今天若米知识就给我们广大朋友来聊聊静态方法与单例,以下关于观点希望能帮助到您找到想要的答案。

静态内部类方法构建单例模式创建ThreadPoolExecutor线程池

最佳答案之前写过一篇 java线程池ThreadPoolExecutor使用无界队列LinkedBlockingQueue实现多线程 简单记录了下ThreadPoolExecutor使用无界队列LinkedBlockingQueue实现多线程的用法。但是在实际应用中,有些并发量大的请求场景,直接如此用会被同时创建多个线程池,会有内存不够用的风险,所以可以考虑用单例模式来管理线程池的调用。

最简单的办法可以是把初始化的ThreadPoolExecutor用@Bean直接注入到springboot中,这样是单例的,不过这样就变成了公用线程池,用完不能shutdown(),会一直存在应用中占用一点内存,当然springboot也自带了线程池可以直接调用,但是因为是公用的所以配置不能根据不同业务灵活改变,所以必要时候还是自己写一个比较好。

对单例模式不太熟的话可以看下面两篇博文,讲的很详细了,一般实现方式有饿汉式、懒汉式、双重检测和静态内部类的方法实现单例,综合使用场景,我觉得静态内部类的方法最适合。

单例模式参考博文链接:

下面就用静态内部类的方法创建一个单例来管理ThreadPoolExecutor的创建:

业务测试方法:

注意,这种自己创建的线程池用完之后要及时关闭,考虑到并发的情况,当线程池存在且没有被关闭时也可以同时处理其他并发的调用,shutdown之后再调用时会重新生成一个新的线程池继续接收处理请求。这样兼顾了占用内存和性能。测试时第一个请求size赋值1000,同时第二个请求size赋值为1,当size为1的请求处理完毕,线程池被关闭之后,第一个请求还没有处理完,剩余的请求会创建一个新的线程池继续处理剩余的请求,处理完之后会关闭线程池,这样用起来不同业务场景可以新建不同配置,比较灵活,用完即关也比较节省内存。

单例模式中唯一实例为什么要用静态?

最佳答案单例模式中唯一实例为什么要用静态?想要回答这个问题,你需要明白单例模式是如何实现的。从本质上理解清楚实现原因,前面的问题也就解决了。

单例模式实现过程如下:

首先,将该类的构造函数私有化(目的是禁止其他程序创建该类的对象);

其次,在本类中自定义一个对象(既然禁止其他程序创建该类的对象,就要自己创建一个供程序使用,否则类就没法用,更不是单例);

最后,提供一个可访问类自定义对象的类成员方法(对外提供该对象的访问方式)。

说直白一点,你不能用该类在其他地方创建对象,而是通过该类自身提供的方法访问类中的那个自定义对象。

那么问题的关键来了,程序调用类中方法只有两种方式,①创建类的一个对象,用该对象去调用类中方法;②使用类名直接调用类中方法,格式“类名::方法名()”;

上面说了,构造函数私有化后第一种情况就不能用,只能使用第二种方法。

而使用类型直接点用类中的方法,类种方法必须是静态的,而静态方法不能访问非静态成员变量,因此类自定义的实例变量也必须是静态的。这就是单例模式唯一实例必须设置为静态的原因。

讨论静态变量加静态方法更好还是单例

最佳答案无生命周期的用static,有生命周期的不用static。

需要用到面向对象行为特征的不用static,static本身不属于面向对象范畴,用了static,无法多态。

static是常驻内存的,不会被回收的,没有生命的。

说一下你用单例跟static的区别在哪。

单例的话你这个对象永远在堆内存,因为有个static的引用一直指向这个对象,所以GC不会去回收。

全部写成static方法和static变量就不一样了,这个时候你整个类中所有东西都是在方法区,即perm区的,永远不会回收。必须伴随着class的卸载而卸载。

所以在写java程序时,尽量少用static,避免perm区爆炸。

类中静态方法和实例方法的区别

最佳答案1、调用方式上

静态方法依赖于类,通过类.静态方法调用;实例方法依赖于类的对象,需要创建对象后,对象.实例方法使用

2、使用上

实例方法内部不能定义静态变量,会出现编译错误;实例方法可以直接调用静态方法;静态方法内部可以定义和使用实例变量,静态方法无法直接调用实例方法(因静态方法加载时类还没有实例化,实例方法依赖于类的对象)

3、静态方法和实例方法的内存分配问题

一般认为静态方法常驻内存,实例方法只有在使用时才分配内存。但事实上,是一样的,都是在类被加载时常驻内存。static方法和non-static方法在创建实例对象时,属性的值对各个对象各不相同(每个实例对象的所有字段在内存中有一个拷贝,用于区分操作哪个对象的字段),new一个实例时,会把实例属性放在GC Heap里面,同时new的对象放在堆栈上,堆栈指针指向刚才拷贝的的内存地址;而静态方法中的静态字段只有一份;对于static和non-static方法代码都是一样的,所以只需要一份代码,占用一份内存空间。调用上因实例方法需要实例化分配内存,静态方法则不用,故静态方法会快一点,但也可忽略不计

4、区分静态方法和实例方法的原因

早期结构化编程几乎所有方法都是静态方法,引入实例化方法的概念是在面向对象概念出现以后,区分静态方法和实例方法不能单单从性能上理解。创建c++、java、c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题

5、适用场景

静态方法:一个方法与类的对象无关,如工具类等

实例方法:一个方法依赖于类的对象;多线程场景下,如果静态方法中含有静态变量,如果对静态变量进行更改操作易造成线程安全问题

6、静态方法与单例模式

如果一个方法与对象的实例无关用静态方法,反之采用实例方法,但如果方法和对象的实例有关,又想维护一份实例时,需要用单例模式。如系统运行时,需要加载一些的配置和属性,是公共的,需要在整个生命周期存在,只需要一份就可以,但此时这些配置和属性又是通过面向对象的编码方式得到的,虽然用静态方法也能解决,但最好的方式是采用单例模式

看完本文,相信你已经对静态方法与单例有所了解,并知道如何处理它了。如果之后再遇到类似的事情,不妨试试若米知识推荐的方法去处理。

本文来自网络,不代表本站立场,转载请注明出处:https://www.rm2g.com/meishi/5378.html

作者: 若米知识

若米知识为您提供最全面的生活百科网站大全,主要为您提供数码、汽车、财经、美食、财经、科技、健康、教育、创业、电商、影视、百科等资讯信息,在这里可以找到您所需的答案,解决您所困惑的问题。
看阳痿大概要多少费用
清朝铜盆
联系我们

联系我们

0898-88881688

在线咨询: QQ交谈

邮箱: email@wangzhan.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部