Java 中,究竟如何使用静态变量?

2016-08-18 11:17:53 +08:00
 miaoxia

曾见过一个大牛的观点:

  1. 代码中的静态变量最好不要超过 10 个。
  2. 而且静态变量要去序列化,当找不到这个变量时再解冻。

他说的是否有道理?


现在有这样一个需求:

如果我把这个 thread pool 定义为 static ,会有什么坏处吗

6195 次点击
所在节点    Java
33 条回复
bigapple111
2016-08-18 12:08:44 +08:00
如果只是说坏处的话,如果涉及到应用场景的话,我相信每个人都有自己的想法,

这个问题应该是 “如果我把这个 thread pool 定义为 static ,会有什么好处吗?”
前文提到 “内存中只保留一份,不需要频繁创建和销毁”

你的应用需要频繁创建 ThreadPool ?
miaoxia
2016-08-18 12:30:45 +08:00
@bigapple111 感谢你的回复
前文提到的只是静态变量的优点,和场景无关。
应用肯定不需要频繁创建 threadPool ,而且想如何去避免频繁创建 threadPool 。
所以才会去假设,将 threadPool 设置成 static 后,会不会实现我预期的目的,
而且是否可能带来什么问题。
miaoxia
2016-08-18 12:32:14 +08:00
@bigapple111
如果不设置为 static ,每 new 一个子类的时候
都会创建一个新的 threadPool 吧
我就是希望可以避免这个问题,能让所有子类共享父类的 threadPool 。
tobyxdd
2016-08-18 13:02:42 +08:00
没必要为了别人因为他们项目特点总结的条条框框影响自己项目架构 ThreadPool 弄成 Static 再正常不过了
ghostsf
2016-08-18 13:27:47 +08:00
根据实际需求来,很明显,这里需要 static
bigapple111
2016-08-18 13:41:11 +08:00
@miaoxia

如果不设置为 static ,每 new 一个子类的时候
都会创建一个新的 threadPool 吧
我就是希望可以避免这个问题,能让所有子类共享父类的 threadPool 。

static 确实能避免上述的问题,大胆的写吧
bigapple111
2016-08-18 13:43:17 +08:00
@miaoxia 或者你自己实现一个单例的 ThreadTaskService ,父类里面定义这个 Service,也一样能达到你想要的效果
SoloCompany
2016-08-18 13:44:18 +08:00
1 static 不应该使用一定意义上是正确的
2 threadpool 应该注入来解决
shimanooo
2016-08-18 13:53:11 +08:00
静态常量可以有
YORYOR
2016-08-18 14:26:22 +08:00
static 可以,系统启动时 生成一个单例的 pool 也可以
cloudzhou
2016-08-18 15:10:34 +08:00
1 使用单例化
2 注入
miaoxia
2016-08-18 15:26:25 +08:00
@tobyxdd
@ghostsf
@bigapple111
感谢回复 会小心谨慎的使用 static
miaoxia
2016-08-18 15:30:58 +08:00
@bigapple111
@YORYOR
@cloudzhou
感谢回复 单例是一种解决方式
不过仍有些疑惑 单例不也是通过 static 方式实现的吗

是否有以下假设:
将需要共享的元从宿主中分离出来,做成单例(仍是 static 的)
就避免 static 可能产生的问题?
miaoxia
2016-08-18 15:37:46 +08:00
@SoloCompany 非常感谢
开拓了新思路

再请教下 通过 Constructor 还是 seter 来实现呢?
在我看来既然已经实现了异步方式, threadPool 的实例是一定要注入的
既 使用 Constructor 方式来实现

但在子类的 Constructor 里,还需要传入其他业务相关的参数
感觉一个业务类的 Constructor 里并列注入一个 threadPool ,看起来有点突兀- -

由于业务能力尚浅,可能有些比较幼稚的观点,请指教
miaoxia
2016-08-18 15:38:03 +08:00
@shimanooo 感谢回复
YORYOR
2016-08-18 15:39:44 +08:00
@miaoxia 单例可以通过 static 实现,也可以你自己在系统启动时仅在系统内 生成一个 final 类型的即可,类似 spring 中的 bean 貌似都是单例的
slixurd
2016-08-18 16:24:17 +08:00
@YORYOR Spring 的 Bean 是 singleton 这个只是 scope 默认配置而已,你配个 prototype 就不一样了。
单例什么的和 static field 没有必然关系,只是因为 static field 一定只存在一份,所以经常用来做单例而已。
什么 double check idiom 之类的
asj
2016-08-18 17:24:53 +08:00
只应该拿来定义常量。
如你问题里描述的需求,应该用 Spring 或者其他框架来管理对象的生命周期,而非依赖语言特性。
SoloCompany
2016-08-18 21:02:30 +08:00
@miaoxia

static 不建议使用主要有两点:容易造成内存泄漏,强耦合,强耦合的问题尤其严重。

注入的方式有很多种,不依赖框架的话,构造方法或者 setter 方法或者单独的 init 方法都是可取的,用 Spring 之类的依赖注入当然就更简单了,其它比如容器提供 jndi 注册也是一种选择,总而言之有很多种方法可以实现单例, static 是看上去省事但却是最坏的选择
hinkal
2016-08-19 01:06:30 +08:00
这个需求很适合 static ,不过可以考虑下真的是这个需求吗?譬如“多个子类想共享一个父类的线程池”,高耦合,子类想访问线程池中的对象?或许可以抽象出一个线程池控制器,通过代理者进行交互。因此最好从设计上改变,减少不必要 static 的使用。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/300107

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX