robertfang
2004-10-27 15:17
上贴我已经说了 放置句柄是32位操作,不会发生损坏现象,是你自己没看清楚就回帖吧,

但是put(key,value)并不一定就只
是放置句柄,当第一次put的一个不存在地key时候,还要生成一个mapEntity,也就是说,这个时候并不只是一次32位操作,
java文档上也说了当hashmap结构上发生改变得时候并不是线程安全的,请你看清楚再说。

robertfang
2004-10-27 15:22
不过是把一个对象的引用放到map分配的空间里而已
-------------------------------------------
如果是put一个第一次出现的key,你是不是要
1 分配空间建立entity,
2 把引用放进去


另外,看 程序员的都认识你,要珍惜自己的形象

cafebabe
2004-10-27 22:06
多个线程并发写一个非同步的map可能会有问题吧,
有可能会破坏map内的数据结构。
感觉而已,没有仔细考虑,回头看看HashMap的实现。

cafebabe
2004-10-27 22:29
反编译了jdk1.5 HashMap,
public Object put(Object obj, Object obj1)
{
Object obj2 = maskNull(obj);
int i = hash(obj2);
int j = indexFor(i, table.length);
for(Entry entry = table[j]; entry != null; entry = entry.next)
if(entry.hash == i && eq(obj2, entry.key))
{
Object obj3 = entry.value;
entry.value = obj1;
entry.recordAccess(this);
return obj3;
}

modCount++;//position 1
addEntry(i, obj2, obj1, j);
return null;
}

void addEntry(int i, Object obj, Object obj1, int j)
{
Entry entry = table[j];
table[j] = new Entry(i, obj, obj1, entry);
if(size++ >= threshold)
resize(2 * table.length);
}

put就是往HashMap里加数据啦,
addEntry(int i, Object obj, Object obj1, int j)就是在第
j个散列桶的头上加上新的一项。
如果两个线程都往这个HashMap里加同一个key,这个key还不存在,
那两个线程可能同时执行到position 1的位置,这两个线程再执行
下去。。。,那这个散列桶里要出现两个一样的key了。

其实我根本不必要费这么大劲举这个例子,光看看addEntry的代码就应该知道多个线程写肯定有问题。

robertfang
2004-10-27 23:01
en 还是这样比较直接 你用什么反编译的?

zdbj2ee
2004-10-28 08:26
还是好好看一下spring的单实例集实现,标准.

anonymous
2004-10-28 09:09
第一,要看HashMap的源码根本用不着反编译,Sun网站提供了JDK源码下载。
第二,看到这段源码又怎样?无非是再次证明了我前面说过的话而已。HashMap的确并发不安全,但不可能出现对象引用失效。
我怎么觉得这里讨论那么累呀,老是要帮别人补习大学本科一年级的常识。

robbin
2004-10-28 10:12
>>我怎么觉得这里讨论那么累呀,老是要帮别人补习大学本科一年级的常识。

在错误的场所对错误的人讨论错误的问题,所以就很累,呵呵。

robertfang
2004-10-28 11:36
1 我当然知道src文件夹的存在,只是惊异于什么反编译工具可以把代码组织的这么好

2 你根本就没有搞明白我说的什么问题

我要解决读写,写写冲突,但是不想太影响性能,所以不能用hashtable,用hashmap的化有什么办法解决
而你口口生生说出现并发又怎样?大不了下一秒的覆盖上一秒的

我说这样不对,因为hashmap不是线程安全的,两个put并发会因起问题,第一次说的原因是句柄的损坏,这个发现是错的,句柄操作是原子的;后来找到第二个原因, put操作并不一定是原子的,

第二个\df 原因说明 出现并发又怎样?大不了下一秒的覆盖上一秒的
这句话根本是错的,因为可能根本就破坏了结构

最终我从Doug Lea那里找到了解决问题的答案

觉得和你说话真的太费劲了,你根本就没看清人家说什么,总要帮你补习中学语文
到此为止
对解决方案感兴趣的人可以看
http://www-900.ibm.com/developerWorks/cn/java/j-jtp07233/
http://www-106.ibm.com/developerworks/java/library/j-jtp08223/

robertfang
2004-10-28 11:43
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);
}


请问你,这里有任何一个地方需要同步吗?如果压根不需要同步,又哪来的什么“性能问题”呢?
---------------------
大家都来看看 ,被并发访问函数getTemperature(String city) 里出现
put 说“这里有任何一个地方需要同步吗?”,用hashmap 你说要不要?

cafebabe
2004-10-28 19:20
手头没有jdk源码就顺手反编译了一下呀。
我好像没说错啥呀,就事论事呀,惹的几位。。。
好无辜呀:(

wm_creat
2004-10-29 11:47
都吵啥啊,个讨论个的去了,要对事不对人。
凡事都做最坏的打算,现在就是性能和可靠性冲突,解决问题不是技术上,而是需求上,需求是温度这个东西根本不用刷新的很快(一小时刷一次问题都不大),这样就是说存储温度可靠性要求大于性能,所以用同步存储方法就可以,而那个读温度的自然是性能要求更高了,这时用异步方法读数据就行了。

简单的说就是同步存数据方法,异步取数据的方法。至于选什么数据结构,我管他什么线程安全呢,我在调用的方法级上控制就行了。

Readonly
2004-10-29 12:52
引用 robertfang 的原话:
------
第二个原因说明 出现并发又怎样?大不了下一秒的覆盖上一秒的
这句话根本是错的,因为可能根本就破坏了结构
------

破坏结构? 偶倒是第一次听说Java里面有破坏结构这个说法, 那么请教, 你所说的破坏结构的后果是什么:

偶下次用map.get(key)获得的对象是null?
或者获得的对象是一个异型?
还是程序会抛出runtime exception?
甚至导致JVM crash?

cafebabe
2004-10-29 20:38
>破坏结构<
每个对象内部的数据结构肯定有一定的约束吧,
当这种约束因为某种原因(比如说并发写)被破坏了,
那这个对象还能正常工作吗?

to Readonly:
请你仔细看下HashMap的代码吧,我想应该一眼就能看出吧。

Readonly
2004-10-29 22:02
偶的小脑袋连破坏结构是什么意思都理解不了, 更别说理解那段犹如天书Native方法的Hashmap代码了......

偶只想了解的是, 当破坏结构发生的时候, 到底会发生什么诡异的结果呢:

偶下次用map.get(key)获得的对象是null?
或者获得的对象是一个异型?
还是程序会抛出runtime exception?
甚至导致JVM crash?

如果你们表达不清楚的话, 写个简单的unit test代码, 来模拟一下发生破坏结构时候的情形吧, hoho......