Benq在以前的帖子中曾建议“使用Spring时,仔细考虑是否到底需要使用Singleton,能不用尽量不用。”
我们现在反过来看看,这句话也不尽合理吧?
是不是应该改为“慎重考虑所提供的bean类在实际应用中,多线程情况下的处理方式”,而不是一句简单的“能不用Singleton就不用Singleton”
Benq在以前的帖子中曾建议“使用Spring时,仔细考虑是否到底需要使用Singleton,能不用尽量不用。”
我们现在反过来看看,这句话也不尽合理吧?
是不是应该改为“慎重考虑所提供的bean类在实际应用中,多线程情况下的处理方式”,而不是一句简单的“能不用Singleton就不用Singleton”
|
|
|
|
还是说几句吧。
有关“破坏结构”这个词,我认为是说对约定的数据结构规则的破坏
在只有一个key的时候size=2 也许你不care,对你没有什么影响 但是确确实实违反了对map的约定。这应该是没有什么辩驳的。
也许在这个应用里无关大局,但是也许在某些地方这就是定时炸弹。
目前除了size问题之外,不知道还没有其他的例子说明并发引起的问题?大家可以都想想。算是互相提高吧.
另外,Lea 是这方面的权威,觉得目前还是应该相信他,起码他的方法万无一失
许多没有正确同步的程序在某些情况下似乎工作得很好,例如在轻微的负载下、在单处理器系统上,或者在具有比 JMM 所要求的更强的内存模型的处理器上。
这篇文章也许有用 http://www-900.ibm.com/developerWorks/cn/java/j-jtp02244/
在段落:Using the example with IoC中,第一个就是:Singletons are evil。
注意这篇文章是在最近发表的,可不是在我之前,否则又有人说我“抄袭”了。
根据上面的 2 3 原则来分析下面的程序:
这样的程序,如果大部分时间耗费在calcTemperature上,那么这个程序应该用下面的程序来代替:
private Map _tempCache;
public Long getTemperature(String city) {
if(!_tempCache.contains(city)) {
Long result = calcTemperature(city);
_tempCache.put(city, result);
}
return (Long) _tempCache.get(city);
}
//替换程序
private Map _tempCache;
public Long getTemperature(String city)
{
//直接获取
Long result = _tempCache.get(city);
if (result == null) {
//如果不存在 Double Checking
synchronized(this) {
//因为内存操作比起计算或者从数据库获取快很多
result = _tempCache.get(city);
if (result == null) {
result = calcTemperature(city);
_tempCache.put(city, result);
}
}
}
return result;
}
|
Page 19, line 7 (excluding code)
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class BreakHashMap
{
private static final int THREAD_COUNT = 500;
private static final BooleanLock startLock = new BooleanLock();
private static final IntLock endLock = new IntLock();
public static void main(String[] args)
{
while (true)
{
System.out.print(".");
final Map map = new HashMap();
// init locks
endLock.count = THREAD_COUNT;
startLock.locked = true;
// construct THREAD_COUNT threads
for (int i = 0; i < THREAD_COUNT; i++)
{
new Thread()
{
public void run()
{
//System.out.print("#");
// wait for main thread to kick off
synchronized (startLock)
{
try
{
while (startLock.locked)
{
startLock.wait();
}
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
// put the same key value pair
map.put("key1", "value1");
//如果象下面这样,再put一个,结果就是正确的了,为什么呢?
map.put("key2", "value2");
//map.put("key3", "value3");
synchronized (endLock)
{
endLock.count--;
if (endLock.count == 0)
{
// notify main thread
endLock.notify();
}
}
}
}.start();
}
// kick off
synchronized (startLock)
{
startLock.locked = false;
startLock.notifyAll();
}
// wait for all other thread to end
try
{
synchronized (endLock)
{
while (endLock.count > 0)
{
endLock.wait();
}
}
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
// check map size
synchronized (map)
{
if (map.size() > 1)
{
System.out.println("\nsize: " + map.size());
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext())
{
String strKey = (String)iterator.next();
System.out.println(map.get(strKey));
}
break;
}
}
// failed, continue
}
}
}
class BooleanLock
{
boolean locked;
}
class IntLock
{
int count;
}