- 浏览: 28877 次
- 性别:
- 来自: 北京
最新评论
先说说我要实现的要求:我要一个Map,这个Map是常量,但是它要进行初始化,填充数据。而且这个Map要可以重用,实现优雅点的
以上是我写的一个方式,总觉得别扭,大家一块看看有什么更好的方法。
2010年6月更新:
这个东西看着确实不是东西,有静态初始化块了,没必要有getter了,实在是。。。
嗯,我那个测试程序就是来说明这一点的。我愿意为 JVM 不会“自动加锁”,可是测试结果表明 JVM 会“自动加锁”,所以表明我以前的想法是错的。
锁只是为了多线程的数据同步而已
如果加载类 只是一个线程的话 那又哪来锁的概念???
你这样为某种现象强加自圆其说的解释 对后来人是会造成误解的
我的例子里有7个并发线程在访问同一个数据,当然是涉及到多线程的数据同步了,怎么会只有一个线程呢。
嗯,我那个测试程序就是来说明这一点的。我愿意为 JVM 不会“自动加锁”,可是测试结果表明 JVM 会“自动加锁”,所以表明我以前的想法是错的。
锁只是为了多线程的数据同步而已
如果加载类 只是一个线程的话 那又哪来锁的概念???
你这样为某种现象强加自圆其说的解释 对后来人是会造成误解的
嗯,仔细看了下确实是我搞错了。
你搞错了,双重检查的例子中不是这样的。他这个例子连双重检查都没有达到。
先不考虑“双重检查”是否能实现,“双重检查”例子的初衷是避免每次都执行影响性能的同步代码,所以“双重检查”例子的同步代码是在第二次检查中的,不是第一次,所以你看到的连双重检查都不是,而是一种很简单的一般同步代码,性能很差的一种(因为每次都要同步)。
双重检查的例子如下:
这个很好理解,表面上同步的实现,并不仅仅是加锁才能实现的,仅仅是一种效果。
这牵涉到JVM的类加载机制,仅仅是一个保证在调用前,类加载能够确保加载完毕,仅此而已,至于用了什么技术来确保接加载完毕,这个方法多了去了,并一定只有加锁才能实现吧。
我指的是yyjn12的回复。我在我的回复中引用了yyjn12的发言。但你似乎理解成了我在针对楼主的代码来说的。
这个没必要在追究了。
第二个问题,我的意思是,如果类加载的机制决定了根本不可能出现并发加载的情况,那就不必说什么“自动加锁”的话。比如,java中给一个整型的变量赋值时,是线程安全的,我们总不能说成“在给整型赋值时,jvm给它自动加了锁”吧?会让人犯晕的。这个我去了解一下类加载机制吧。
你搞错了,双重检查的例子中不是这样的。他这个例子连双重检查都没有达到。
先不考虑“双重检查”是否能实现,“双重检查”例子的初衷是避免每次都执行影响性能的同步代码,所以“双重检查”例子的同步代码是在第二次检查中的,不是第一次,所以你看到的连双重检查都不是,而是一种很简单的一般同步代码,性能很差的一种(因为每次都要同步)。
双重检查的例子如下:
这个很好理解,表面上同步的实现,并不仅仅是加锁才能实现的,仅仅是一种效果。
这牵涉到JVM的类加载机制,仅仅是一个保证在调用前,类加载能够确保加载完毕,仅此而已,至于用了什么技术来确保接加载完毕,这个方法多了去了,并一定只有加锁才能实现吧。
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
这里一旦加了同步synchronized,就不再是你说的那个“无效双重检查锁”了。
但是我照样不推崇,因为同步锁在极端情况下会严重影响性能的。
他加上双重检查就是为了在第二次访问时不必再执行同步那一段了,因为原有的代码在判断if (approveCodeMap.isEmpty())时需要获得锁 ,但实际上,第一次访问之后,已经setApprove()了,以后的访问还需要获得锁,这种开销就很不必要了。这是他加双重检查的目的,所以无所谓“影响性能”。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
另,关于那个“自动加锁”的比喻,我不理解的地方在于:难道存在这种情况——类加载的过程会被并发访问(并发加载)?
他们说的“自动上锁”只是个比喻。
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
这里一旦加了同步synchronized,就不再是你说的那个“无效双重检查锁”了。
但是我照样不推崇,因为同步锁在极端情况下会严重影响性能的。
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
这样不就ok了!
你这个就是Java的饿汉式单例模式。
这样不就ok了!
这个spring的初始化功能是指的哪一部分呢?愿闻其详~~
你看第三页最后一段,我写了。
这里给个简单例子。
这个。。。最好把你碰到的情况详细说一下(例如static代码块如果有依赖于访问数据库的操作,那是最好换一种思路了)。
一般来说web.xml中可以指定初始化的顺序(例子我现在没有,明天到单位才),比如有一个类叫做com.javaeye.Driver,那只要最优先触发一下Class.forName("com.javaeye.Driver")就可以了。
说管说,真要做的话,因为我使用Spring,使用Spring的初始化功能来做的(要例子的话明天给)。static只能做做简单的初始化,例如map的初始化等等,复杂的初始化最好不要用static代码块。
这个spring的初始化功能是指的哪一部分呢?愿闻其详~~
嗯,这个测试代码已经很明显地显示了static块加载的时间了~呵呵~
public class ApproveMap { private static Map<String, String> approveCodeMap = new HashMap<String, String>(); /** * @return */ public static Map<String, String> getApprove() { synchronized (approveCodeMap) { if (approveCodeMap.isEmpty()) setApprove(); } return approveCodeMap; } private static void setApprove() { /** * */ approveCodeMap.put("101102", "11_0003_0001"); approveCodeMap.put("101103", "11_0003_0004"); approveCodeMap.put("101104", "11_0003_0005"); approveCodeMap.put("101105", "11_0003_0002"); approveCodeMap.put("101106", "11_0003_0003"); approveCodeMap.put("101107", "11_0003_0006"); } }
以上是我写的一个方式,总觉得别扭,大家一块看看有什么更好的方法。
2010年6月更新:
这个东西看着确实不是东西,有静态初始化块了,没必要有getter了,实在是。。。
public class ApproveMap { public static final Map<String, String> approveCodeMap = new HashMap<String, String>(); static { /** * */ approveCodeMap.put("101102", "11_0003_0001"); approveCodeMap.put("101103", "11_0003_0004"); approveCodeMap.put("101104", "11_0003_0005"); approveCodeMap.put("101105", "11_0003_0002"); approveCodeMap.put("101106", "11_0003_0003"); approveCodeMap.put("101107", "11_0003_0006"); } }
评论
60 楼
xcly
2009-03-18
结贴,不要复杂化
59 楼
andot
2009-03-13
insiku 写道
andot 写道
找不到服务器 写道
初始化需要同步这个思想是正确的,但是不需要我们去显式的干这个事情,JVM会"自动加锁"
比如,线程T1调用某个类A,若A没有被加载,那么A会被JVM加载,如果在加载的过程中有其他线程T2也要调用A,T2那么只能等待,而不是再去加载。也许在加载过程中T1的时间片到期,但是T2还是会继续阻塞,直到A被加载完成。所以这个过程就好像JVM自动加锁了一样。。。。。。。。。。。
比如,线程T1调用某个类A,若A没有被加载,那么A会被JVM加载,如果在加载的过程中有其他线程T2也要调用A,T2那么只能等待,而不是再去加载。也许在加载过程中T1的时间片到期,但是T2还是会继续阻塞,直到A被加载完成。所以这个过程就好像JVM自动加锁了一样。。。。。。。。。。。
嗯,我那个测试程序就是来说明这一点的。我愿意为 JVM 不会“自动加锁”,可是测试结果表明 JVM 会“自动加锁”,所以表明我以前的想法是错的。
锁只是为了多线程的数据同步而已
如果加载类 只是一个线程的话 那又哪来锁的概念???
你这样为某种现象强加自圆其说的解释 对后来人是会造成误解的
我的例子里有7个并发线程在访问同一个数据,当然是涉及到多线程的数据同步了,怎么会只有一个线程呢。
58 楼
insiku
2009-03-13
andot 写道
找不到服务器 写道
初始化需要同步这个思想是正确的,但是不需要我们去显式的干这个事情,JVM会"自动加锁"
比如,线程T1调用某个类A,若A没有被加载,那么A会被JVM加载,如果在加载的过程中有其他线程T2也要调用A,T2那么只能等待,而不是再去加载。也许在加载过程中T1的时间片到期,但是T2还是会继续阻塞,直到A被加载完成。所以这个过程就好像JVM自动加锁了一样。。。。。。。。。。。
比如,线程T1调用某个类A,若A没有被加载,那么A会被JVM加载,如果在加载的过程中有其他线程T2也要调用A,T2那么只能等待,而不是再去加载。也许在加载过程中T1的时间片到期,但是T2还是会继续阻塞,直到A被加载完成。所以这个过程就好像JVM自动加锁了一样。。。。。。。。。。。
嗯,我那个测试程序就是来说明这一点的。我愿意为 JVM 不会“自动加锁”,可是测试结果表明 JVM 会“自动加锁”,所以表明我以前的想法是错的。
锁只是为了多线程的数据同步而已
如果加载类 只是一个线程的话 那又哪来锁的概念???
你这样为某种现象强加自圆其说的解释 对后来人是会造成误解的
57 楼
huangdan817
2009-03-04
使用静态块
56 楼
mhz_1986
2009-03-03
静态初始化不错,简洁!
55 楼
icewubin
2009-03-01
pipilu 写道
我指的是yyjn12的回复。我在我的回复中引用了yyjn12的发言。但你似乎理解成了我在针对楼主的代码来说的。
这个没必要在追究了。
这个没必要在追究了。
嗯,仔细看了下确实是我搞错了。
54 楼
pipilu
2009-03-01
icewubin 写道
pipilu 写道
他加上双重检查就是为了在第二次访问时不必再执行同步那一段了,因为原有的代码在判断if (approveCodeMap.isEmpty())时需要获得锁 ,但实际上,第一次访问之后,已经setApprove()了,以后的访问还需要获得锁,这种开销就很不必要了。这是他加双重检查的目的,所以无所谓“影响性能”。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
你搞错了,双重检查的例子中不是这样的。他这个例子连双重检查都没有达到。
先不考虑“双重检查”是否能实现,“双重检查”例子的初衷是避免每次都执行影响性能的同步代码,所以“双重检查”例子的同步代码是在第二次检查中的,不是第一次,所以你看到的连双重检查都不是,而是一种很简单的一般同步代码,性能很差的一种(因为每次都要同步)。
双重检查的例子如下:
private Resource resource; public Resource getResource() { if (resource == null) { synchronized(this) { if (resource==null) { resource = new Resource(); } } } return resource; }
pipilu 写道
另,关于那个“自动加锁”的比喻,我不理解的地方在于:难道存在这种情况——类加载的过程会被并发访问(并发加载)?
这个很好理解,表面上同步的实现,并不仅仅是加锁才能实现的,仅仅是一种效果。
这牵涉到JVM的类加载机制,仅仅是一个保证在调用前,类加载能够确保加载完毕,仅此而已,至于用了什么技术来确保接加载完毕,这个方法多了去了,并一定只有加锁才能实现吧。
我指的是yyjn12的回复。我在我的回复中引用了yyjn12的发言。但你似乎理解成了我在针对楼主的代码来说的。
这个没必要在追究了。
第二个问题,我的意思是,如果类加载的机制决定了根本不可能出现并发加载的情况,那就不必说什么“自动加锁”的话。比如,java中给一个整型的变量赋值时,是线程安全的,我们总不能说成“在给整型赋值时,jvm给它自动加了锁”吧?会让人犯晕的。这个我去了解一下类加载机制吧。
53 楼
icewubin
2009-03-01
pipilu 写道
他加上双重检查就是为了在第二次访问时不必再执行同步那一段了,因为原有的代码在判断if (approveCodeMap.isEmpty())时需要获得锁 ,但实际上,第一次访问之后,已经setApprove()了,以后的访问还需要获得锁,这种开销就很不必要了。这是他加双重检查的目的,所以无所谓“影响性能”。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
你搞错了,双重检查的例子中不是这样的。他这个例子连双重检查都没有达到。
先不考虑“双重检查”是否能实现,“双重检查”例子的初衷是避免每次都执行影响性能的同步代码,所以“双重检查”例子的同步代码是在第二次检查中的,不是第一次,所以你看到的连双重检查都不是,而是一种很简单的一般同步代码,性能很差的一种(因为每次都要同步)。
双重检查的例子如下:
private Resource resource; public Resource getResource() { if (resource == null) { synchronized(this) { if (resource==null) { resource = new Resource(); } } } return resource; }
pipilu 写道
另,关于那个“自动加锁”的比喻,我不理解的地方在于:难道存在这种情况——类加载的过程会被并发访问(并发加载)?
这个很好理解,表面上同步的实现,并不仅仅是加锁才能实现的,仅仅是一种效果。
这牵涉到JVM的类加载机制,仅仅是一个保证在调用前,类加载能够确保加载完毕,仅此而已,至于用了什么技术来确保接加载完毕,这个方法多了去了,并一定只有加锁才能实现吧。
52 楼
pipilu
2009-03-01
icewubin 写道
pipilu 写道
yyjn12 写道
在
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
这里一旦加了同步synchronized,就不再是你说的那个“无效双重检查锁”了。
但是我照样不推崇,因为同步锁在极端情况下会严重影响性能的。
他加上双重检查就是为了在第二次访问时不必再执行同步那一段了,因为原有的代码在判断if (approveCodeMap.isEmpty())时需要获得锁 ,但实际上,第一次访问之后,已经setApprove()了,以后的访问还需要获得锁,这种开销就很不必要了。这是他加双重检查的目的,所以无所谓“影响性能”。
但是,在一个线程持有锁执行setApprove()时,另一个线程approveCodeMap.isEmpty()的判断会为false,那返回的是没有初始化完全的approveCodeMap。这不是开发者期望的。
另外,不提倡双重检查的原因主要是“内存的无序写入”的问题。
http://www.ibm.com/developerworks/cn/java/j-dcl.html
这个问题在之前javaeye的一个帖子的回复中被讨论过。
另,关于那个“自动加锁”的比喻,我不理解的地方在于:难道存在这种情况——类加载的过程会被并发访问(并发加载)?
51 楼
icewubin
2009-02-28
pipilu 写道
static区块应该是jvm负责运行的,我想不出有什么可能性会使它被“并发访问”??我们怎么去并发访问它?
莫非类加载器会启动多个线程去加载这个类? 想不明白。
关于“自动给static加上锁”,我用javap看了一下jvm指令,没看到“monitorenter”和“monitorexit”指令,没理由证明static被自动加上锁了。
莫非类加载器会启动多个线程去加载这个类? 想不明白。
关于“自动给static加上锁”,我用javap看了一下jvm指令,没看到“monitorenter”和“monitorexit”指令,没理由证明static被自动加上锁了。
他们说的“自动上锁”只是个比喻。
50 楼
icewubin
2009-02-28
pipilu 写道
yyjn12 写道
在
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
这里一旦加了同步synchronized,就不再是你说的那个“无效双重检查锁”了。
但是我照样不推崇,因为同步锁在极端情况下会严重影响性能的。
49 楼
pipilu
2009-02-28
static区块应该是jvm负责运行的,我想不出有什么可能性会使它被“并发访问”??我们怎么去并发访问它?
莫非类加载器会启动多个线程去加载这个类? 想不明白。
关于“自动给static加上锁”,我用javap看了一下jvm指令,没看到“monitorenter”和“monitorexit”指令,没理由证明static被自动加上锁了。
莫非类加载器会启动多个线程去加载这个类? 想不明白。
关于“自动给static加上锁”,我用javap看了一下jvm指令,没看到“monitorenter”和“monitorexit”指令,没理由证明static被自动加上锁了。
48 楼
xiaoZ5919
2009-02-28
static语句块 就可以了
47 楼
pipilu
2009-02-28
yyjn12 写道
在
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
# synchronized (approveCodeMap) {
# if (approveCodeMap.isEmpty())
# setApprove();
# }
的外边,再加一层 if(approveCodeMap.isEmpty())
双重检查锁,效率会比这个高很多。
这个不成了,每次取这个map都要排队了吗
已经有很多文章说明双重检查锁是行不通的,为什么还有人在推崇呢?
46 楼
icewubin
2009-02-27
zhajie 写道
public class testDao { private testDao () { } private static testDao config = new testDao (); private Map<String, Map<String,Config>> configs = null; public static testDao getInstance() { return config; } public void inCache() { if(configs==null) configs = new ConcurrentHashMap<String, Map<String,Config>>(); } }
这样不就ok了!
你这个就是Java的饿汉式单例模式。
45 楼
zhajie
2009-02-27
public class testDao { private testDao () { } private static testDao config = new testDao (); private Map<String, Map<String,Config>> configs = null; public static testDao getInstance() { return config; } public void inCache() { if(configs==null) configs = new ConcurrentHashMap<String, Map<String,Config>>(); } }
这样不就ok了!
44 楼
icewubin
2009-02-27
blurm 写道
这个spring的初始化功能是指的哪一部分呢?愿闻其详~~
你看第三页最后一段,我写了。
这里给个简单例子。
icewubin 写道
<bean id="driver" class="com.javaeye.Driver" init-method="init"/>
43 楼
jwinder
2009-02-27
推崇
satic { ...... }
42 楼
blurm
2009-02-27
icewubin 写道
andot 写道
能不能说一下,Class.forName()在何时调用,就是说写在代码的哪个位置,对这个比较感兴趣,以前没接触过这个,所以一直都是在 static 块中加锁来保证线程不会冲突的,因为原来没加锁时,确实遇到过线程冲突的问题。就是在 Web 服务器上部署是遇到的。
这个。。。最好把你碰到的情况详细说一下(例如static代码块如果有依赖于访问数据库的操作,那是最好换一种思路了)。
一般来说web.xml中可以指定初始化的顺序(例子我现在没有,明天到单位才),比如有一个类叫做com.javaeye.Driver,那只要最优先触发一下Class.forName("com.javaeye.Driver")就可以了。
说管说,真要做的话,因为我使用Spring,使用Spring的初始化功能来做的(要例子的话明天给)。static只能做做简单的初始化,例如map的初始化等等,复杂的初始化最好不要用static代码块。
这个spring的初始化功能是指的哪一部分呢?愿闻其详~~
41 楼
jieyuan_cg
2009-02-26
andot 写道
经过实际测试发现,我原来认为的是错的。确实静态 static 块自己会加锁,不需要再手工用同步块加锁了。下面是测试代码:
运行结果:
package teststatic; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; public class MyStatic { private static HashMap<String, String> map = new HashMap<String, String>(); static { try { System.out.println("start init"); map.put("101101", "11_0003_0007"); Thread.sleep(1000); map.put("101102", "11_0003_0001"); Thread.sleep(1000); map.put("101103", "11_0003_0004"); Thread.sleep(1000); map.put("101104", "11_0003_0005"); Thread.sleep(1000); map.put("101105", "11_0003_0002"); Thread.sleep(1000); map.put("101106", "11_0003_0003"); Thread.sleep(1000); map.put("101107", "11_0003_0006"); System.out.println("end init"); } catch (InterruptedException ex) { Logger.getLogger(MyStatic.class.getName()).log(Level.SEVERE, null, ex); } } public static String getData(String key) { return map.get(key); } }
package teststatic; public class Main { public static void main(String[] args) throws InterruptedException { for (int i = 1; i < 8; i++) { final int n = i; Runnable r = new Runnable() { public void run() { System.out.println("start call" + n); System.out.println(MyStatic.getData("10110" + n)); System.out.println("end call" + n); } }; new Thread(r).start(); Thread.sleep(50); } } }
运行结果:
start call1 start init start call2 start call3 start call4 start call5 start call6 start call7 end init 11_0003_0006 end call7 11_0003_0007 end call1 11_0003_0002 11_0003_0005 end call4 11_0003_0001 end call2 11_0003_0003 11_0003_0004 end call3 end call5 end call6
嗯,这个测试代码已经很明显地显示了static块加载的时间了~呵呵~
发表评论
-
页面声明遵循的w3c标准很重要。。。
2010-11-05 20:57 907因为没有添加类似<!DOCTYPE html PUBLI ... -
Aapche2.2和PHP5.2以及Mysql5.0的整合配置
2008-07-17 10:58 1273因为公司的一个PHP论坛要升级,以前的负责人已经离职,不得已, ... -
symbio面试之后~
2008-02-22 15:32 2984昨天下午去symbio(一个做外包的)面试了,面的是j ... -
讨厌的webwork xml解析~~
2007-04-28 09:21 1261前两天用webwork和hibernate+spring搭了个 ... -
有关于spring
2007-05-16 06:03 9561.关于spring管理的bean中的变量命名问题:变量名为小 ... -
观点一:Web2.0站点经常囊括了来自一个或者多个第三方站点的数据,这称为“mash-up”。 观点...
2007-05-21 02:19 1053观点一:Web2.0站点经常囊括了来自一个或者多个第三方站点的 ...
相关推荐
QT静态单例管理信号和槽是Qt框架中一种常见的设计模式,用于确保应用程序中只有一个特定类的实例。在Qt编程中,单例模式通常用于管理全局资源,如数据库连接、配置文件读取或系统设置。这里我们将深入探讨如何在Qt中...
在Java中,有多种实现单例的方式,包括饿汉式、懒汉式、双重检查锁定(DCL)、静态内部类和枚举。这里我们将重点讨论静态内部类和枚举实现单例的过程。 首先,让我们来看看静态内部类实现单例的方式: ```java ...
单例模式是软件设计模式中的一种,用于控制类的实例化过程,确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统中需要频繁创建和销毁的对象,或者需要共享资源的情况下非常有用。然而,实现单例模式时,...
在Java中,单例模式可以通过多种方式实现,包括懒汉式、饿汉式、双重检查锁定和静态内部类方法等。今天,我们主要介绍了Java单例模式实现静态内部类方法示例,涉及构造函数私有化等相关内容。 单例模式的定义 单例...
通过`SingletonFactory`工具类,我们不仅可以方便地使用各种单例模式,还可以对自定义的单例进行统一管理和访问,提高了代码的可维护性和灵活性。在实际开发中,应根据项目需求选择适合的单例实现方式,以保证代码的...
在Joomla!涉及到了很多的单例模式,比如JFactory,JURI等等。 对于一个请求中需要一个对象实例的,joomla大多采用了单例模式,可以避免重复实例化带来的资源浪费和性能损耗。
单例模式的核心思想是限制类的实例化过程,确保在程序运行期间,类的实例只有一个。通过控制类的构造函数,使其不能被外部直接实例化,而是通过一个静态方法来获取唯一的实例。这样,无论何时何地,只要调用这个静态...
Java 中的静态变量、静态方法、静态块和静态类 Java 中的静态变量、静态方法、静态块和静态类是 Java 编程语言的四个重要概念,它们之间存在着紧密的关系。下面将对这四个概念进行详细的介绍。 一、静态变量...
此外,单例模式还有几种变体,比如静态内部类单例和枚举单例。静态内部类单例利用Java类加载机制保证了线程安全,而枚举单例则是Java中实现单例的最佳方式,因为它天然支持序列化且防止反射攻击。 在代码实现上,...
静态内部类单例利用JVM保证了类加载的线程安全性,而枚举单例则是一种既简洁又线程安全的实现方式,也是官方推荐的单例实现方式。 ```java public enum Singleton { INSTANCE; // ... } ``` 在使用单例模式时,...
单例模式与静态类(一个类,所有方法为静态方法)是另一个非常有趣的问题,在《Java中有关单例模式的面试问题》博文中露掉了,由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例如,两者可以直接...
在上面的代码中,我们定义了一个 SingletonMode 类,它有一个私有的构造方法和一个公有的静态方法 getInstance()。getInstance() 方法用于获取 SingletonMode 的实例,如果实例不存在,则创建一个新的实例。 测试...
静态内部类单例模式利用了Java语言中静态内部类的特性来实现单例模式。具体来说它将单例对象的创建延迟到静态内部类被加载时才执行,从而避免了多线程环境下的同步问题。下面是一个简单的示例代码: ```java public...
//单例模式,始终只产生一个对象 /*public class SingleTest { public static void main(String[] args) { SingleTon singleTon1=SingleTon.getInstance(); SingleTon singleTon2=SingleTon.getInstance(); ...
静态内部类实现单例模式5. 饿汉实现单例模式6. 饿汉变种实现单例模式7. 枚举实现单例模式static修饰下是怎么做到线程安全的?完全不使用synchronized实现单例模式1. CAS(AtomicReference)实现单例模式2. ...
然而,如果不正确地处理单例,特别是在涉及动态库和静态库的情况下,可能会导致各种问题,甚至引发程序崩溃。标题和描述所提到的"singleton_crash"就是这种情况的一个实例,它探讨了当静态库被多个动态库链接时,...
根据内部类是否声明为static,它们被分为非静态内部类(也称为成员内部类)和静态内部类。 #### 二、静态内部类的特点 静态内部类具有以下特点: 1. **独立性**:静态内部类与外部类之间没有依赖关系,即使外部类...
在这个特定的场景中,我们讨论的是一个实现了单例模式的日志类,该类专为多线程环境设计,具备日志等级控制、精确的时间戳以及可变长参数和标准格式化输出的功能。 首先,让我们深入了解单例模式。单例模式的主要...
- 静态内部类单例:利用类加载机制保证线程安全,避免了同步开销。 4. **工具类设计**: - `DB.java`:可能包含静态方法,如`getConnection()`,返回数据库连接。使用单例模式确保全局只存在一个`Connection`实例...