"=="和java中重写equals方法法究竟有什么区别?

Error_404_资源不存在
404. 抱歉! 您访问的资源不存在!
请确认您输入的网址是否正确,如果问题持续存在,请发邮件至contact&#与我们联系。&通过jconsole(或者thread dump),可以看到线程停在了transfer方法的while循环处&&&
"通过jconsole(或者thread dump),可以看到线程停在了transfer方法的while循环处"
分析多线程并发写HashMap线程被hang住的原因
kafka0102 发表于 日 05:05 | Hits: 4367Tag: java | HashMap
在blogjava上看到一文谁能帮忙解释一下为什么这个程序会死锁?,激发了我那能害死猫的好奇,所以很费劲的琢磨了这个问题。由于涉及的内容较多,就单独发文阐述一下。
文中提到的问题程序如下:
public class TestLock {
private final HashMap map = new HashMap();
public TestLock() {
final Thread t1 = new Thread() {
public void run() {
for(int i=0; i&500000; i++) {
map.put(new Integer(i), i);
System.out.println("t1 over");
final Thread t2 = new Thread() {
public void run() {
for(int i=0; i&500000; i++) {
map.put(new Integer(i), i);
System.out.println("t2 over");
t1.start();
t2.start();
public static void main(final String[] args) {
new TestLock();
就是启了两个线程,不断的往一个非线程安全的HashMap中put内容,put的内容很简单,key和value都是从0自增的整数(这个put 的内容做的并不好,以致于后来干扰了我分析问题的思路)。对HashMap做并发写操作,我原以为只不过会产生脏数据的情况,但反复运行这个程序,会出现 线程t1、t2被hang住的情况,多数情况下是一个线程被hang住另一个成功结束,偶尔会两个线程都被hang住。说到这里,你如果觉得不好好学习 ConcurrentHashMap而在这瞎折腾就手下留情跳过吧。
好吧,分析下HashMap的put函数源码看看问题出在哪,这里就罗列出相关代码(jdk1.6):
public V put(final K key, final V value) {
if (key == null) {
return putForNullKey(value);
final int hash = hash(key.hashCode());
final int i = indexFor(hash, table.length);
for (Entry&K,V& e = table[i]; e != e = e.next) {//@标记1
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
final V◇◇Value = e.
e.recordAccess(this);
return◇◇V
modCount++;
addEntry(hash, key, value, i);
}&void addEntry(final int hash, final K key, final V value, final int bucketIndex) {
final Entry&K,V& e = table[bucketIndex];
table[bucketIndex] = new Entry&K,V&(hash, key, value, e);
if (size++ &= threshold) {
resize(2 * table.length);
}&void resize(final int newCapacity) {
final Entry[]◇◇Table =
final int◇◇Capacity =◇◇Table.
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
final Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newT
threshold = (int)(newCapacity * loadFactor);
}&void transfer(final Entry[] newTable) {
final Entry[] src =
final int newCapacity = newTable.
final long time1 = System.currentTimeMillis();
for (int j = 0; j & src. j++) {
Entry&K,V& e = src[j];
if (e != null) {
int k=0;//@标记2
final Entry&K,V& next = e.
final int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] =
if (k++ & 1000) {//@标记3
System.out.println(Thread.currentThread().getName()+
",e==next:"+(e==e.next)+",e==next.next:"+(e==e.next.next)+
",e:"+e+",next:"+e.next+",eq:"+e.equals(e.next));
Thread.sleep(2000);
} catch (final Exception e2) {
} while (e != null);
通过jconsole(或者thread dump),可以看到线程停在了transfer方法的while循环处。这个transfer方法的作用是,当Map中元素数超过阈值需要resize 时,它负责把原Map中的元素映射到新Map中。我修改了HashMap,加上了@标记2和@标记3的代码片断,以打印出死循环时的状态,结果死循环线程 总是出现类似这样的输出:“Thread- 1,e==next:false,e==next.next:true,e:928,next:928,eq:true”。
这个输出表明:
1)这个Entry链中的两个Entry之间的关系是:e=e.next.next,造成死循环。
2)e.equals(e.next),但e!=e.next。因为测试例子中两个线程put的内容一样,并发时可能同一个key被保存了多个value,这种错误是在addEntry函数产生的,但这和线程死循环没有关系。
接下来就分析transfer中那个while循环了。先所说这个循环正常的功能:src[j]保存的是映射成同一个hash值的多个Entry的链表,这个src[j]可能为null,可能只有一个Entry,也可能由多个Entry链接起来。假设是多个Entry,原来的链是(src[j]=a)-&b(也就是src[j]=a,a.next=b,b.next=null),经过while处理后得到了(newTable[i]=b)-&a。也就是说,把链表的next关系反向了。
再看看这个while中可能在多线程情况下引起问题的语句。针对两个线程t1和t2,这里它们可能的产生问题的执行序列做些个人分析:
1)假设同一个Entry列表[e-&f-&...],t1先到,t2后到并都走到while中。t1执行“e.next = newTable[i];newTable[i] =”这使得e.next=null(初始的newTable[i]为null),newTable[i]指向了e。这时t2执行了“e.next = newTable[i];newTable[i] =”,这使得e.next=e,e死循环了。因为循环开始处的“final Entrynext = e.”,尽管e自己死循环了,在最后的“e =”后,两个线程都会跳过e继续执行下去。
2)在while中逐个遍历Entry链表中的Entry而把next关系反向时,newTable[i]成为了被交换的引用,可疑的语句在于“e.next = newTable[i];”。假设链表e-&f-&g被t1处理成eg,造成了死循环。所以,理论上来说,死循环的Entry个数可能很多。尽管产生了死循环,但是t1执行到了死循环的右边,所以是会继续执行下去的,而t2如果执行“final Entrynext = e.”的next为null,则也会继续执行下去,否则就进入了死循环。
3)似乎情况会更复杂,因为即便线程跳出了死循环,它下一次做resize进入transfer时,有可能因为之前的死循环Entry链表而被hang住(似乎是一定会被hang住)。也有可能,在put检查Entry链表时(@标记1),因为Entry链表的死循环而被hang住。也似乎有可能,活着的线程和死循环的线程同时执行在while里后,两个线程都能活着出去。所以,可能两个线程平安退出,可能一个线程hang在transfer中,可能两个线程都被hang住而又不一定在一个地方。
4)我反复的测试,出现一个线程被hang住的情况最多,都是e=e.next.next造成的,这主要就是例子put两份增量数据造成的。我如果去掉@标记3的输出,有时也能复现两个线程都被hang住的情况,但加上后就很难复现出来。我又把put的数据改了下,比如让两个线程put范围不同的数据,就能复现出e=e.next,两个线程都被hang住的情况。
上面罗哩罗嗦了很多,一开始我简单的分析后觉得似乎明白了怎么回事,可现在仔细琢磨后似乎又不明白了许多。有一个细节是,每次死循环的key的大小也是有据可循的,我就不打哈了。感觉,如果样本多些,可能出现问题的原因点会很多,也会更复杂,我姑且不再蛋疼下去。至于有人提到ConcurrentHashMap也有这个问题,我觉得不大可能,因为它的put操作是加锁的,如果有这个问题就不叫线程安全的Map了。
被转藏 : 1次
被转藏 : 1次
一年一个台阶啊,升级成功拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3ad102d253b34ce4-ua98).
重新安装浏览器,或使用别的浏览器您访问的页面不见了!对中华法系的再认识
——兼论“诸法合体,民刑不分”说不能成立
我国学界用现代法学观点研究中国相关信息史始于清末。从那时到现在近百年来,有关中华法系的探讨一直没有间断。不仅许多法史著述特别是法律通史类教材、著作对中华法系进行了论述,而且有几部研究中华法系的专著和大量的专题论文发表,提出了不少有学术价值的见解。然而,在这一研究领域也出现了一些认识上的误区,如把“诸法合体,民刑不分”说成是中华法系或律典的基本特征;以现见的几部律典为依据描绘中华法系,贬低或否定刑律之外其它法律形式的作用;往往......
对中华法系的再认识
——兼论“诸法合体,民刑不分”说不能成立
我国学界用现代法学观点研究中国相关信息史始于清末。从那时到现在近百年来,有关中华法系的探讨一直没有间断。不仅许多法史著述特别是法律通史类教材、著作对中华法系进行了论述,而且有几部研究中华法系的专著和大量的专题论文发表,提出了不少有学术价值的见解。然而,在这一研究领域也出现了一些认识上的误区,如把“诸法合体,民刑不分”说成是中华法系或律典的基本特征;以现见的几部律典为依据描绘中华法系,贬低或否定刑律之外其它法律形式的作用;往往从“君主专制工具”的视角而不是全面、科学地阐述中华法系的基本精神;对有关中华法系一些重要问题的论证也有不实之论。
正确地认识中华法系及其特征,是科学地阐述中国法律发展史必须解决的关键问题。鉴于中国古代法律史研究中存在的一些重大缺陷多是与如何认识中华法系有关,也鉴于有关中华法系的特征等一些重要问题至今仍存在争论,而这些争论又直接影响着法史研究能否朝着科学的方向开拓。为此,就中华法系研究中的一系列重大问题继续进行探讨甚有必要。本文侧重就“诸法合体,民刑不分”是不是中华法系或律典的特征及相关问题谈谈个人的拙见。
一、近百年来围绕“诸法合体,民刑不分”说的探讨
认为“诸法合体,民刑不分”是中华法系特征的观点由来已久。《政法论坛》2001年第3期发表的《中国古代的法律体系与法典体例》一文说:“20世纪30年代以来,法律史学者在总结传统的中华法系的特点时,提出了‘诸法合体,民刑不分’的观点,影响了半个世纪”。据我看到的两则资料,“诸法合体,民刑不分”说提出的时间恐怕还要早。1907年(清光绪三十三年)民政部奏文云:“中国律例,民刑不分,……历代律文户婚诸条,实近民法”[1]。李祖荫为介绍《古代法》一书所作的《小引》云:日本有的法学家把《古代法》作者梅因的“大凡半开化的国家,民法少而刑法多”的观点,奉为至理名言,“据此对我国大肆诬蔑,说中国古代只有刑法而没有民法,是一个半开化的、文化低落的国家。就在我国,也有一些资产阶级法学家象鹦鹉学舌一样,把自己的祖先辱骂一顿。事实上,古代法律大抵都是诸法合体,并没有什么民法、刑法的分别,中国古代是这样,外国古代也是这样。”[2]由此又可推知,提出“诸法合体,民刑不分”说者,是外国人先于中国学者。究竟此说最早是由谁人提出,有待详考。但20世纪30年代中国学者著述中的“诸法合体,民刑不分”说,实际上是对在此之前类似看法的沿袭或概括而已。
20世纪三十、四十年代,我国学界曾围绕中华法系进行过热烈的学术探讨。著名法史学者陈顾远、丁元普、程树德等发表了一系列研究中华法系的论文,洋洋数万言。其中陈顾远先后发表了《天道观念与中国固有法系之关系》、《儒家思想与中国固有法系之关系》、《家族制度与中国固有法系之关系》等多篇论文。他在《我国过去无‘民法法典’之内在原因》[3]一文中,分别从程序法和实体法的角度,对中华法系“民刑不分”说提出质疑。二十世纪六十年代末,他在《中国文化与中国法系》[4]这本专著中,对中华法系进行了较为系统的阐发,提出了不少灼识卓见,并再次对“民刑不分”说予以批驳。
然而,在近数十年间,陈顾远等有关中华法系的研究成果,在我国大陆法史学界未受到应有的重视。而“诸法合体,民刑不分”是中华法系的基本特征这一观点,却被广泛沿用。从1982年出版的高等学校法学试用教材《中国法制史》[5]到1998年出版的高等政法院校规划教材《中国法制史》,[6]都持这一看法,并进而作了理论阐发。中国人民大学出版社1981年出版的《中国法制史》是新中国成立以后较早沿用“诸法合体,民刑不分”这一论断的法史著作,该书《绪论》写道:“从战国时李悝著《法经》起,直到封建末世的《大清律》,历代具有代表性的法典基本上都是刑法典,同时也包含着民法、行政法、诉讼法等各方面的内容,这种混合编纂的结构形式,就是通常所说‘民刑不分’,‘诸法合体’”。
多年来,已发表的不少法史著述特别是一些法律通史类著作和论文,也是按照这一认识模式去阐发中国法律发展史的。受“诸法合体,民刑不分”说的影响,有些中国法律史的教材,以律典编纂史来替代中国立法史,而对行政、经济、民事、军事等方面的法律制度和法律思想很少涉及。许多本来被前人澄清的不确之论,在一些著述中还作为学术见解大加阐发。
在当代我国大陆学者中,较早对“诸法合体,民刑不分”是中华法系特征这一观点提出质疑和修正的是张晋藩先生。1988年,他在《再论中华法系的若干问题》[7]一文中论述中华法系的特点时,把“民刑不分,诸法合体与民刑有分,
用金山词霸在线查出来的朗文英汉综合电脑词典QUOT= QUOTient,商(数),系数[英汉] 英汉航海大词典n.开...的价,报...的价 ...[英汉] 英...
念奴娇·赤壁怀古 · 苏东坡 大江东去,浪淘尽、千古风流人物。 故垒西边,人道是、三国周郎赤壁。 乱石崩云,惊涛裂岸,卷起千堆雪。 江山如画,一时多少豪杰! 遥...
姓氏:申屠
祖宗:申侯
分类:复姓
姓氏起源: 1、为上古舜帝的后代。初为胜屠氏,后因古代“胜”与“申”两字同音,故俗称申屠氏。2、出自姜姓,为炎帝裔孙四...
白话一点就是脑力劳动者是管人的,体力劳动者是被人管的
半殖民地半封建社会是当时的一大社会背景,在这一背景下,使得封建礼法之争必须有一个决断,旧的法律已经不能适应新的社会关系,必须制定新的法律。于是有了一系列的清末变...
答: 选择了闪住,退房后多长时间会退回押金?
答: 1、“对方又不是律师”:学长是怎么知道对方不是律师的?既然如此,你是不是也有办法知道对方到底是干什么的了?如果是知名的法学专家、教师、法官、检察官、法律栏目主持...
答: 法律是什么?虽然在日常生活中我们都用到法律一词,但是它的用法如此之多,使这个问题没有简单的答案。法律的定义取决于我们如何看它的目的和功能。在社会中法律的一个基本...
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区

我要回帖

更多关于 assertequals方法 的文章

 

随机推荐