??xml version="1.0" encoding="utf-8" standalone="yes"?>超清首页国产亚洲丝袜,亚洲乱码卡一卡二卡三,亚洲av成人片在线观看http://www.tkk7.com/rainmanyang/zh-cnTue, 13 May 2025 01:27:52 GMTTue, 13 May 2025 01:27:52 GMT60发现自己人性的qQ从现在开始,惛_p充!http://www.tkk7.com/rainmanyang/archive/2009/01/29/252675.htmlrainmanrainmanWed, 28 Jan 2009 16:38:00 GMThttp://www.tkk7.com/rainmanyang/archive/2009/01/29/252675.htmlhttp://www.tkk7.com/rainmanyang/comments/252675.htmlhttp://www.tkk7.com/rainmanyang/archive/2009/01/29/252675.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/252675.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/252675.html        q一切的一切都来自源于我自认ؓq有些高的学历,q种自以为是没有帮助我在学业和h际上有所斩获Q却危害C与朋友与家h的关pR这个问题自己早早已l有所察觉Q但都一直没有引以ؓ戒。h贵自知,其实我知道自己ƈ没有自己认ؓ得那么优UQ但Zl护自己在别人面前的形象Q给自己I上了一个外壟뀂思A有点乱,写的有点׃八糟。古Z日一省,写了半天Q今天首先ȝ我的W一个弱点:1.自以为是Q有些时候过于自大?

rainman 2009-01-29 00:38 发表评论
]]>
生命是一个长期积累的q程http://www.tkk7.com/rainmanyang/archive/2008/12/22/247801.htmlrainmanrainmanMon, 22 Dec 2008 10:01:00 GMThttp://www.tkk7.com/rainmanyang/archive/2008/12/22/247801.htmlhttp://www.tkk7.com/rainmanyang/comments/247801.htmlhttp://www.tkk7.com/rainmanyang/archive/2008/12/22/247801.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/247801.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/247801.html 许多同学应该都还记得联考前夕的焦虑Q差一分可能要掉好几个志愿Q甚至于一生的?br /> q从此改观!C大四Q这U焦虑可能更强烈而复杂:到底要先当兵Q就业,q是先?br /> 研究所Q我q常碰到学生充满焦虑的问我q些问题。可是,q些焦虑实在是莫L?br /> Q生命是一U长期而持l的累积q程Q绝不会因ؓ单一的事件而毁了一个h的一生,?br /> 不会因ؓ单一的事件而救了一个h的一生。属于我们该得的Q迟早会得到Q属于我们不
该得的,即侥幸巧取也不可能长久保有。如果我们看清这个事实,许多所?人生的重
大抉择就可以淡然处之Q根本无需焦虑。而所?人生的困?Q也往往当下变得无?br /> 挂?br /> 我自己就是一个活生生的例子。从一q大学就军_不再늠I所Q所以,大学四年的时
间多半在念h文科学的东西。毕业后工作了几q_才决定要늠I所。硕士毕业后Q立
下决心:从此不再为文凭而念书。谁知道Q世事难料,当了五年讲师后,我又被时势所
q,出国念博士?nbsp;
出国Ӟ一位大学同学笑我:全班最晚念博士的都要回国了Q你现在才要出去Q两q后
 我从剑桥回来Q觉得h生际遇无常,莫此为甚Q一个从大一决定再也不钻营学位的h
Q竟然连士和博士都拿到了!属于我们该得的,哪样曄过Q而h生中该得与不?br /> 得的I竟有多,我们又何曄晓?从此我对际遇一事不能不更加淡然?nbsp;
当讲师期_有些态度较极端的学生会当面表现出他们的不屑;从剑桥回来时Q却被学
生当做不得了的事看待。这U表面上的大起大落,其实都是好事者之aQ完全看不到?br /> 实的真相。从表面上看来,两年拿到剑桥博士,q好像很了不赗但是,在这两年?br /> 前我已经花整整一q_研I主题有关的论文全部看完Qƈ扑և研究方向Q而之前更?br /> ׃q时间做控制斚w的研IӞq且在国际着名的学术期刊中发表论文。而从士毕业
到拿博士Q期间七q的旉我从不停止过研究与自修?nbsp;所以,q个博士其实是篏U了?br /> q的成果Q或者,只算我花在控制学门的旉Q也臛_有五q_Q根本也没什么好惊讶
的?nbsp;
思h不从长期而持l的累积q程来看待生命因U蓄而有的成果,老爱在表面上以断裂?br /> 孤立的事件夸大议论,因此每每在^淡无奇的事g上强做悲喜。可是对我来Ԍ当讲?br /> 期间被学生瞧不vQ以及剑桥刚回来时被同学夸大本事Q都只是表象。事实是Q我只在
乎每天二十四时点点滴滴的篏U?nbsp;
拿硕士或博士只是特定时刻里这些成果篏U的外在展示而已Qh生命中真实的累积从不
曑֛q些事g而终止或d?nbsp;
常有学生满怀忧虑的问我:"老师Q我很想先当完兵Q工作一两年再考研I所。这样好?br /> Q? 
"很好Q这样子有机会先用实务来印证学理Q你늠I所时会比别Z解自p的是什?br /> ? 
"可是Q我怕当完兵又工作后Q会失去斗志Q因此考不上研I所? 
"那你先考研I所好了? 
"可是Q假如我先念研究所Q我怕自己又会像念大学时一栯Ӟ因此늚不甘不愿的?br /> " 
"那你q是先去工作好了Q?nbsp;" 
"可是。。。。。。?nbsp;
我完全可以体会到他们的焦虑,可是却无法压抑住对于q种话的感慨。其实,说穿了他
所需要的是两年研究所加两q工作,以便加深知识的深q度和获取实务经验?nbsp;
先工作或先升学,表面上大相迳庭,其实骨子里的差别Ҏ可以忽略?nbsp;
?朝三暮四"q个成语故事里,Mh原本喂养猴子的橡实是"早上四颗下午三颗"Q后?br /> 改ؓ"朝三暮四"Q猴子就不高兴而坚持改回到"朝四暮三"。其实,先工作或先升学,?br /> 间差异就有如"朝三暮四"?朝四暮三"Q原不值得计较。但是,我们l常看不到这U生
命过E中长远而持l的累积Q老爱一旉遇中的小差别夸大到生L关的地步?nbsp;  
最讽刺的是Q当我们面对两个可能的方案,而焦虑得不知如何抉择Ӟ通常表示q两?br /> Ҏ可能一样好Q或者一样坏Q因而实际上选择哪个都一P唯一的差别只是先后之?br /> 而已。而且Q愈是让我们焦虑得厉害的Q其实差别越,愈不值得焦虑。反而真正有?br /> 昄好坏差别Ӟ我们L的就知道该怎么做了。可是我们却l常看不到长q的来Q?br /> 短视的盯着两案短期内的得失Q想选甲案,p不得乙案的好处;想选乙案,又舍不得
甲案的好处。如果看得够q,人生长则八、九十,短则五、六十年Q先做哪一件事又有
什么关p?甚至当完兵又工作后,再花一整年准备研究所Q又有什么了不vQ当Ӟ?br /> 些hq是会忧虑说Q?我当完兵又工作后Q会不会因ؓ家篏或记忆力衰退而比较难考上?br /> I所Q? 我只能这样回{:"一个h考不上研I所Q只有两个可能:或者他不够聪明Q或
者他的确够聪明。不够聪明而考不上,那也没什么好抱怨的。假如你够聪明,q考不?br /> 研究所Q那只能说你的决心不够强。假如你是决心不够强Q就表示你生命中q有其他?br /> 可能性,光要程度ƈ不下于硕士学位,而你舍不得丢下他。既然如此,考不上研I所
也无L到遗憾。不是吗Q?人生的\q么多,Z么要老斤斤计较着一个可能性? 
我高中最要好的朋友,一生背q:高中考两ơ,高一念两ơ,大学又考两ơ,甚至q机
车驾照都考两ơ。毕业后Q他告诉自己Q我没有关系Q也没有学历Q只能靠加倍的诚恳
和努力。现在,他自己拥有一家公司,q收入数千万?nbsp;
一个h在升学过E中不顺利,而在事业上顺利,q是常见的事。有才华的hQ不会因?br /> 被名校拒l而连带失M的才华,只不q要另外N合他表现的场所而已。反q来Q一
个h在升学过E中太顺利,也难免因而放不下w段d业,而只能乖乖领薪水q活?nbsp;
兮兮Q谁人知晓? 我们又有什么好得意Q又有什么好忧虑Qh生的得与失,有时?br /> 怎么也说不清楚,有时候却再简单不q了Q我们得到^日篏U的成果Q而失L们不?br /> 努力累积的!所以重要的不是和别人比成就Q而是努力d自己惛_的。最后该得到?br /> 不会你一分,不该得到的也不会多你一分?nbsp;
好像是前q的时候,我遇C位高中同学。他在南加大当电机系的副教授Q被清华甉|
聘回来开短期评。从高中时代他就很用功,以第一志愿上台大电机后Q四q都拿书?br /> 奖,怿他在专业上的研究也已卓然有成。回想高中入学时Q我们两个h的智力测验成
l分居全学年W一Q第二名。可是从高一我就不曾攑ּ自己喜欢的文学,音乐Q书法,
艺术和哲学,而他却始l不曑ֈ心,因此两个人在学术上的差距只会愈来愈远。反q来
_q十几二十年我在人文领域所获得的满I恐怕已q非他能理解的了。我太太问过
我,如果我肯全心专注于一个研I域,是不是至会赶上q位同学的成?我不q样
惻I两个不同性情的hQ注定要C条不同的路。不该得的东西,我们注定是得不到?br /> Q随随便便拿两个人来比,只看C所得到的,却看不到他所失去的,q有什么意义?
 
有次清华电台讉K我:"老师你如何面对你人生中的困境Q?我当场愣在那里,怎么样都
想不出我q一生什么时候有q困境!后来仔细回想Q才发现Q我不是没有q困境,而是
被常人当?困境"的境遇,我都当作一时的际遇Q不曑֜意过而已。刚服完兵役Ӟ?br /> 子已出生却还找不到工作。我曄虑过Q却又觉得迟早会有工作,报酬也不至于低的?br /> 谱,不曾太放在心上。念士期间Q家计全靠太太的薪水Q省吃P用,Ҏ而言又算?br /> 上困境。一来精上我过的很充实Q二来我知道q一切是Z让自己有Z转行L?br /> (做自己想做的?。三十一岁才要出国,而同学正要回pMLQ我很紧?不知道剑?br /> 要求的有多严)Q却不曾丧气。因为,我知道自pM直很努力Q也有很满意的心得和
成果Q只不过别h看不到而已。   
我没有过困境Q因为我从不在乎外在的得失,也不武断的和别h比高下,而只在乎自己
内在真实的篏U?nbsp;   
我没有过困境Q因为我实了解刎ͼ生命是一U长期而持l的累积q程Q绝不会因ؓ?br /> 一的事件而有剧烈的v伏。   
同时我也怿Q属于我们该得的Q迟早会得到Q属于我们不该得的,即一分也不可?br /> 增加。假如你可以持有相同的信念,那么人生于你也会是宽q而长q,没有什么了不得
?困境"Q也没有什么好焦虑的了?

rainman 2008-12-22 18:01 发表评论
]]>
l于毕业了!http://www.tkk7.com/rainmanyang/archive/2008/12/15/246315.htmlrainmanrainmanMon, 15 Dec 2008 01:48:00 GMThttp://www.tkk7.com/rainmanyang/archive/2008/12/15/246315.htmlhttp://www.tkk7.com/rainmanyang/comments/246315.htmlhttp://www.tkk7.com/rainmanyang/archive/2008/12/15/246315.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/246315.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/246315.html       今天Q本以ؓ背了几个月的包袱l于可以怸了,哪知道自己ƈ没有惌得这么洒脱,看来真正的解p{到盲申l果出来后了Qgod bless meQ?br />

rainman 2008-12-15 09:48 发表评论
]]>
U念我的W一份offerhttp://www.tkk7.com/rainmanyang/archive/2008/10/28/237087.htmlrainmanrainmanTue, 28 Oct 2008 05:39:00 GMThttp://www.tkk7.com/rainmanyang/archive/2008/10/28/237087.htmlhttp://www.tkk7.com/rainmanyang/comments/237087.htmlhttp://www.tkk7.com/rainmanyang/archive/2008/10/28/237087.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/237087.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/237087.html        首次p|Q?8奥运是全球的一ơ重大体育盛典,我当然也不例外在它的陪伴下度q了炎热?月,同时Q我的研I生毕业论文也在q段旉完成了初E(后来证实需要做重大修改orzQ。得益于论文完成得比较早Q我可以有_的时间来参加校园招聘的宣讲会和笔试,面试。我的第一场面试是上v亚信Q去的那天天上下着雨Q似乎我人生中的每次转折都伴随着雨天Q中考,高考,考研无不都是阴雨l늉。这ơ面试地点不是在亚信总部Q而是在移动的客服中心。管理得相当严格Q过了好几道门禁才进入他们办公的地方Q第一感觉是一个时办公地点,几张桌子拼成一张大的办工作Q零零散散有人坐在那办公。带我进门的人随侉K了我几句学历情况Q当知道我还没毕业就表现的比较吃惊(I竟有没有仔l看我的历)Q我明确表示可以先实习,看样子他Ҏ的兴就降低了很多,先拿了䆾内部的笔试卷子让我做Q大概有4,前两张都是数据库的题目,大部分是比较基础的,可我也做不来Q那时候对数据库还没有pȝ复习Q也应ؓq,我后一个月看了好几本oracle的书Q算是有了很大的q步。后半部分是java题,做的比较,js的题做得不怎么栗做完后把题目交l带我上来的员工Q他随便看了两下p做的q不错,随便和我blabla了几句就让我回去{消息了。第一ơ面试就q样以失败告l了Q事后ȝ估计是说我还没毕业只能实习就被bs了,q不能怪我吧,历上说的很清楚了Q下ơ接到电话要先和Ҏ认清楚再去Q免得白跑一浪Ҏ情?br />         在支付宝的两ơ失败:9月䆾开始一些大公司的校园招聘就陆陆l箋开始了Q我也结束了?1job和chinahr漫天撒网Q着重于校招公司的网生뀂阿里系的几家公司开始得都比较早Q最早开始的是支付宝,也是我参加的W一场宣讲会。由于自己接触过支付q_的开发,对第三方支付q_的前景比较看好,所以对q次Z特别看重。ȝ来说支付宝的宣讲会还是比较成功的Q前面的那位技术主说话很有煽动力Q很快把大家的兴调动v来了Q短短半个多时的演讲我对W三Ҏ付的现状和前景有了更深刻的认识。第二位hrȝ的口才更是没得说Q将会场带入了另一个高潮,ȝ来说q次宣讲l我的感觉非常棒Q相比较来说我后面参加的|易Q百度等大公司的宣讲p逊色得多了,听到一半就有想睡觉的感觉,毫无Ȁ情。接下来的笔试感觉也比较利Q大部分都有了解Q就是cssQ和js忘得差不多了Q最后两题ؕ写了一通。回到学校已l?2点多了,q次是初尝扑ַ作的艰辛。晚上睡觉一直看着手机Q生怕漏接通知我去面试的电话,谁知天意弄hQ在我昏昏沉沉要睡着时手机竟然没电关ZQ毫无察觉的我一直等得实在撑不住了才q入梦乡。早上破天荒?点就醒来了,失望的拿h边的手机才发现已l关ZQ忙插上充电器打开手机盯着看了五分多钟l于{来了那一条折腾了我一晚的短信Q果真是通知我去面试的。以最快的速度打点完毕Q带上简历直奔浙大,地方不好找,很小的一个入口,q去已经有不h在门口填表了Q一面一个大教室里坐了不h在面试。在门口{了大约半个时有人叫我的名字了,被带C比较靠里的一张桌子前Q面试官看面相相当和|一直对着我微W。后来才知道q家伙是支付宝上L技术主,后来一ơ在支付宝的面试二面也栽在了他手上。第一ơ的面试实在准备上也相当不充分Q很多问题回{的都不是很好,{案都很短,没有深入到细节,可能l他的映像就是我的知识结构都只是停留在表层。事后ȝQ涉及到技术的问题一定要展开_以他的问题ؓ核心辐射开来,q样才能占据d。他如果对你所说的内容感兴的话会l箋问这斚w的问题,如果你的回答只是了了几句Q那他会有别的准备好的问题来提问Q这些问题很可能是你没有涉及到的内容。最后他也问了一些rp问题Q问了我在校期间当学生干部的一些情况,我当时居然告诉他说我当学生干部是被迫的,是因为没q才顶上的。当天最大的败笔在此,做事如此不积极主动的人怎么让别人相信你能承担v一定的责QQ所以在后面的面试中只要有rp斚w的问题我的回{一定是要表现自q极主动的一面,效果非常不错。支付宝的第一ơ面试一面就被打发回MQ但我后面面试经验大多是对这ơ面试中出现的问题ȝ得出的,可以说这ơ失败是q么多次p|中最有h值的一ơ?

rainman 2008-10-28 13:39 发表评论
]]>
ClassLoaderhttp://www.tkk7.com/rainmanyang/articles/234518.htmlrainmanrainmanWed, 15 Oct 2008 13:04:00 GMThttp://www.tkk7.com/rainmanyang/articles/234518.htmlhttp://www.tkk7.com/rainmanyang/comments/234518.htmlhttp://www.tkk7.com/rainmanyang/articles/234518.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/234518.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/234518.html关于Class的是如何加蝲的一直都很模p,也没L么它Q昨天在参加|易的笔试时提到了这个问题。到|上查了查:

下面q一文章是JavaEYE里的Qhttp://www.javaeye.com/topic/83978?page=1

ClassLoader一个经常出现又让很多h望而却步的词,本文试图以最显易懂的方式来讲解 ClassLoaderQ希望能对不了解该机制的朋友起到一点点作用?

要深入了解ClassLoaderQ首先就要知道ClassLoader是用来干什么的Q顾名思义Q它是用来加蝲Class文g到JVMQ以供程序用的。我们知道,javaE序可以动态加载类定义Q而这个动态加载的机制是通过ClassLoader来实现的Q所以可惌知ClassLoader的重要性如何?

看到q里Q可能有的朋友会惛_一个问题,那就是既然ClassLoader是用来加载类到JVM中的Q那么ClassLoader又是如何被加载呢Q难道它不是java的类Q?

没有错,在这里确实有一个ClassLoader不是用java语言所~写的,而是JVM实现的一部分Q这个ClassLoader是bootstrap classloaderQ启动类加蝲器)Q这个ClassLoader在JVMq行的时候加载java核心的API以满javaE序最基本的需求,其中包括用户定义的ClassLoaderQ这里所谓的用户定义是指通过javaE序实现的ClassLoaderQ一个是ExtClassLoaderQ这个ClassLoader是用来加载java的扩展API的,也就?lib/ext中的c,一个是AppClassLoaderQ这个ClassLoader是用来加载用h器上CLASSPATH讄目录中的Class的,通常在没有指定ClassLoader的情况下Q程序员自定义的cdpClassLoaderq行加蝲?

当运行一个程序的时候,JVM启动Q运行bootstrap classloaderQ该ClassLoader加蝲java核心APIQExtClassLoader和AppClassLoader也在此时被加载)Q然后调用ExtClassLoader加蝲扩展APIQ最后AppClassLoader加蝲CLASSPATH目录下定义的ClassQ这是一个程序最基本的加载流E?

上面大概讲解了一下ClassLoader的作用以及一个最基本的加载流E,接下来将讲解一下ClassLoader加蝲的方式,q里׃得不讲一下ClassLoader在这里用了双亲委托模式q行cd载?

每一个自定义ClassLoader都必ȝ承ClassLoaderq个抽象c,而每个ClassLoader都会有一个parent ClassLoaderQ我们可以看一下ClassLoaderq个抽象cM有一个getParent()ҎQ这个方法用来返回当前ClassLoader的parentQ注意,q个parent不是指的被承的c,而是在实例化该ClassLoader时指定的一个ClassLoaderQ如果这个parent为nullQ那么就默认该ClassLoader的parent是bootstrap classloaderQ这个parent有什么用呢?

我们可以考虑q样一U情况,假设我们自定义了一个ClientDefClassLoaderQ我们用这个自定义的ClassLoader加蝲java.lang.StringQ那么这里String是否会被q个ClassLoader加蝲呢?事实上java.lang.Stringq个cdƈ不是被这个ClientDefClassLoader加蝲Q而是由bootstrap classloaderq行加蝲Qؓ什么会q样Q实际上q就是双亲委托模式的原因Q因为在M一个自定义ClassLoader加蝲一个类之前Q它都会先委托它的父亲ClassLoaderq行加蝲Q只有当父亲ClassLoader无法加蝲成功后,才会p己加载,在上面这个例子里Q因为java.lang.String是属于java核心API的一个类Q所以当使用ClientDefClassLoader加蝲它的时候,该ClassLoader会先委托它的父亲ClassLoaderq行加蝲Q上面讲q,当ClassLoader的parent为nullӞClassLoader的parent是bootstrap classloaderQ所以在ClassLoader的最层是bootstrap classloaderQ因此最l委托到bootstrap classloader的时候,bootstrap classloader׃q回String的Class?

我们来看一下ClassLoader中的一D|代码Q?/p>

 1protected synchronized Class loadClass(String name, boolean resolve)    
 2throws ClassNotFoundException    
 3    {    
 4// 首先查该name指定的class是否有被加蝲    
 5Class c = findLoadedClass(name);    
 6if (c == null{    
 7    try {    
 8    if (parent != null{    
 9        //如果parent不ؓnullQ则调用parent的loadClassq行加蝲    
10= parent.loadClass(name, false);    
11     }
 else {    
12        //parent为nullQ则调用BootstrapClassLoaderq行加蝲    
13         c = findBootstrapClass0(name);    
14     }
    
15     }
 catch (ClassNotFoundException e) {    
16        //如果仍然无法加蝲成功Q则调用自n的findClassq行加蝲                
17         c = findClass(name);    
18     }
    
19}
    
20if (resolve) {    
21     resolveClass(c);    
22}
    
23return c;    
24    }
   
25

从上面一D代码中Q我们可以看Z个类加蝲的大概过E与之前我所丄例子是一LQ而我们要实现一个自定义cȝ时候,只需要实现findClassҎ卛_?

Z么要使用q种双亲委托模式呢?

W一个原因就是因样可以避免重复加载,当父亲已l加载了该类的时候,没有必要子ClassLoader再加载一ơ?

W二个原因就是考虑到安全因素,我们试想一下,如果不用这U委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,q样会存在非常大的安全隐患,而双亲委托的方式Q就可以避免q种情况Q因为String已经在启动时被加载,所以用戯定义cL无法加蝲一个自定义的ClassLoader?

上面对ClassLoader的加载机制进行了大概的介l,接下来不得不在此讲解一下另外一个和ClassLoader相关的类Q那是Classc,每个被ClassLoader加蝲的class文gQ最l都会以Classcȝ实例被程序员引用Q我们可以把Classcd作是普通类的一个模板,JVMҎq个模板生成对应的实例,最l被E序员所使用?

我们看到在ClasscM有个静态方法forNameQ这个方法和ClassLoader中的loadClassҎ的目的一P都是用来加蝲class的,但是两者在作用上却有所区别?
Class<?> loadClass(String name)
Class<?> loadClass(String name, boolean resolve)
我们看到上面两个Ҏ声明Q第二个Ҏ的第二个参数是用于设|加载类的时候是否连接该c,truep接,否则׃q接?

说到q接Q不得不在此做一下解释,在JVM加蝲cȝ时候,需要经q三个步骤,装蝲、连接、初始化。装载就是找到相应的class文gQ读入JVMQ初始化׃用说了,最主要p说连接?

q接分三步,W一步是验证class是否W合规格Q第二步是准备,是为类变量分配内存同时讄默认初始|W三步就是解释,而这步就是可选的Q根据上面loadClassҎ的第二个参数来判定是否需要解释,所谓的解释Ҏ《深入JVM》这本书的定义就是根据类中的W号引用查找相应的实体,再把W号引用替换成一个直接引用的q程。有Ҏ奥吧Q呵呵,在此׃多做解释了,惛_体了解就ȝ《深入JVM吧》,呵呵Q再q样一步步解释下去Q那׃知道什么时候才能解释得完了?

我们再来看看那个两个参数的loadClassҎQ在JAVA API 文档中,该方法的定义是protectedQ那也就是说该方法是被保护的Q而用L正应该用的Ҏ是一个参数的那个Q一个参数的loadclassҎ实际上就是调用了两个参数的方法,而第二个参数默认为falseQ因此在q里可以看出通过loadClass加蝲cd际上是加蝲的时候ƈ不对该类q行解释Q因此也不会初始化该cR而ClasscȝforNameҎ则是相反Q用forName加蝲的时候就会将Classq行解释和初始化QforName也有另外一个版本的ҎQ可以设|是否初始化以及讄ClassLoaderQ在此就不多讲了?

不知道上面对q两U加载方式的解释是否_清楚Q就在此举个例子吧,例如JDBC DRIVER的加载,我们在加载JDBC驱动的时候都是用的forName而非是ClassLoader的loadClassҎ呢?我们知道QJDBC驱动是通过DriverManagerQ必dDriverManager中注册,如果驱动cL有被初始化,则不能注册到DriverManager中,因此必须使用forName而不能用loadClass?

通过ClassLoader我们可以自定义类加蝲器,定制自己所需要的加蝲方式Q例如从|络加蝲Q从其他格式的文件加载等{都可以Q其实ClassLoaderq有很多地方没有讲到Q例如ClassLoader内部的一些实现等{,本来希望能够讲得单易懂一点,可是l果自己看回头好像感觉ƈ不怎么P郁闷Q看来自q文笔q是差太多了Q希望能够给一些有需要的朋友一点帮助吧?

另外一是Qhttp://dev.csdn.net/article/68/68103.shtm

静态库、动态连接库

E序~制一般需l编辑、编译、连接、加载和q行几个步骤。在我们的应用中Q有一些公׃码是需要反复用,把q些代码~译?#8220;?#8221;文gQ在q接步骤中,q接器将从库文g取得所需的代码,复制到生成的可执行文件中。这U库UCؓ静态库Q其特点是可执行文g中包含了库代码的一份完整拷贝;~点是被多ơ用就会有多䆾冗余拯?/p>

Z克服q个~点可以采用动态连接库。这个时候连接器仅仅是在可执行文件中打上标志Q说明需要用哪些动态连接库Q当q行E序Ӟ加蝲器根据这些标志把所需的动态连接库加蝲到内存?/p>

另外在当前的~程环境中,一般都提供Ҏ让程序在q行的时候把某个特定的动态连接库加蝲q运行,也可以将其卸载(例如Win32的LoadLibrary()&FreeLibrary()和Posix的dlopen()&dlclose()Q。这个功能被q泛地用于在E序q行时刻更新某些功能模块或者是E序外观?/p>

What is ClassLoader?

与普通程序不同的是,JavaE序Qclass文gQƈ不是本地的可执行E序。当q行JavaE序Ӟ首先q行JVMQJava虚拟机)Q然后再把Java class加蝲到JVM里头q行Q负责加载Java class的这部分叫做Class Loader?/p>

JVM本n包含了一个ClassLoaderUCؓBootstrap ClassLoaderQ和JVM一PBootstrap ClassLoader是用本地代码实现的,它负责加载核心Java ClassQ即所有java.*开头的c)。另外JVMq会提供两个ClassLoaderQ它们都是用Java语言~写的,由Bootstrap ClassLoader加蝲Q其中Extension ClassLoader负责加蝲扩展的Java classQ例如所有javax.*开头的cd存放在JRE的ext目录下的c)QApplication ClassLoader负责加蝲应用E序自n的类?/p>

When to load the class?

什么时候JVM会用ClassLoader加蝲一个类呢?当你使用javaL行一个类QJVM使用Application ClassLoader加蝲q个c;然后如果cA引用了类BQ不是直接引用q是用Class.forName()引用QJVM׃扑ֈ加蝲cA的ClassLoaderQƈ用这个ClassLoader来加载类B?/p>

Why use your own ClassLoader?

gJVM自n的ClassLoader已经_了,Z么我们还需要创qClassLoader呢?

因ؓJVM自带的ClassLoader只是懂得从本地文件系l加载标准的java class文gQ如果编写你自己的ClassLoaderQ你可以做到Q?br /> 1Q在执行非置信代码之前,自动验证数字{֐
2Q动态地创徏W合用户特定需要的定制化构建类
3Q从特定的场所取得java classQ例如数据库?br /> 4) {等

事实上当使用Applet的时候,qC特定的ClassLoaderQ因旉要从|络上加载java classQƈ且要查相关的安全信息?/p>

目前的应用服务器大都使用了ClassLoader技术,即你不需要创qClassLoaderQ了解其原理也有助于更好地部|自q应用?/p>

ClassLoader Tree & Delegation Model

当你军_创徏你自qClassLoaderӞ需要承java.lang.ClassLoader或者它的子cR在实例化每个ClassLoader对象Ӟ需要指定一个父对象Q如果没有指定的话,pȝ自动指定ClassLoader.getSystemClassLoader()为父对象。如下图Q?/p>

在Java 1.2后,java class的加载采用所谓的委托模式QDelegation ModleQ,当调用一个ClassLoader.loadClass()加蝲一个类的时候,遵循以下的步骤Q?br /> 1Q检查这个类是否已经被加载进来了Q?br /> 2Q如果还没有加蝲Q调用父对象加蝲该类
3Q如果父对象无法加蝲Q调用本对象的findClass()取得q个cR?/p>

所以当创徏自己的Class LoaderӞ只需要重载findClass()q个Ҏ?/p>

Unloading? Reloading?

当一个java class被加载到JVM之后Q它有没有可能被卸蝲呢?我们知道Win32有FreeLibrary()函数QPosix有dlclose()函数可以被调用来卸蝲指定的动态连接库Q但是Javaq没有提供一个UnloadClass()的方法来卸蝲指定的类?/p>

在Java中,java class的卸载仅仅是一U对pȝ的优化,有助于减应用对内存的占用。既然是一U优化方法,那么完全是JVM自行军_如何实现Q对Java开发h员来说是完全透明的?/p>

在什么时候一个java class/interface会被卸蝲呢?Sun公司?a >原话是这么说的:"class or interface may be unloaded if and only if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded."

事实上我们关心的不是如何卸蝲cȝQ我们关心的是如何更新已l被加蝲了的cM而更新应用的功能。JSP则是一个非常典型的例子Q如果一个JSP文g被更改了Q应用服务器则需要把更改后的JSP重新~译Q然后加载新生成的类来响应后l的h?/p>

其实一个已l加载的cL无法被更新的Q如果你试图用同一个ClassLoader再次加蝲同一个类Q就会得到异常(java.lang.LinkageError: duplicate class definitionQ,我们只能够重新创Z个新的ClassLoader实例来再ơ加载新cR至于原来已l加载的c,开发h员不必去它Q因为它可能q有实例正在被用,只要相关的实例都被内存回收了Q那么JVM׃在适当的时候把不会再用的cd载?/p>

rainman 2008-10-15 21:04 发表评论
]]>
正确使用 Volatile 变量http://www.tkk7.com/rainmanyang/articles/232766.htmlrainmanrainmanMon, 06 Oct 2008 13:30:00 GMThttp://www.tkk7.com/rainmanyang/articles/232766.htmlhttp://www.tkk7.com/rainmanyang/comments/232766.htmlhttp://www.tkk7.com/rainmanyang/articles/232766.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/232766.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/232766.html阅读全文

rainman 2008-10-06 21:30 发表评论
]]>
ThreadLocal与synchronizehttp://www.tkk7.com/rainmanyang/articles/232633.htmlrainmanrainmanMon, 06 Oct 2008 04:13:00 GMThttp://www.tkk7.com/rainmanyang/articles/232633.htmlhttp://www.tkk7.com/rainmanyang/comments/232633.htmlhttp://www.tkk7.com/rainmanyang/articles/232633.html#Feedback1http://www.tkk7.com/rainmanyang/comments/commentRss/232633.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/232633.html阅读全文

rainman 2008-10-06 12:13 发表评论
]]>
使用dom4j解析XMLhttp://www.tkk7.com/rainmanyang/articles/232558.htmlrainmanrainmanSun, 05 Oct 2008 13:30:00 GMThttp://www.tkk7.com/rainmanyang/articles/232558.htmlhttp://www.tkk7.com/rainmanyang/comments/232558.htmlhttp://www.tkk7.com/rainmanyang/articles/232558.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/232558.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/232558.html阅读全文

rainman 2008-10-05 21:30 发表评论
]]>
再谈ReentrantLockhttp://www.tkk7.com/rainmanyang/articles/232227.htmlrainmanrainmanFri, 03 Oct 2008 09:55:00 GMThttp://www.tkk7.com/rainmanyang/articles/232227.htmlhttp://www.tkk7.com/rainmanyang/comments/232227.htmlhttp://www.tkk7.com/rainmanyang/articles/232227.html#Feedback0http://www.tkk7.com/rainmanyang/comments/commentRss/232227.htmlhttp://www.tkk7.com/rainmanyang/services/trackbacks/232227.html

?/span>入锁Q?span class="hilite1" style="background-color: #ffff00; ">ReentrantLockQ是一U递归无阻塞的同步机制。以前一直认为它是synchronized的简单替代,而且实现机制也不相差太远。不q最q实践过E中发现它们之间q是有着天壤之别?/p>

以下?a target="_blank" style="color: #006699; text-decoration: underline; ">官方说明Q一个可重入的互斥锁?LockQ它h与?synchronized Ҏ和语句所讉K的隐式监视器锁定相同的一些基本行为和语义Q但功能更强大?span class="hilite1" style="background-color: #ffff00; ">ReentrantLock 由最q成功获得锁定,q且q没有释放该锁定的线E所拥有。当锁定没有被另一个线E所拥有Ӟ调用 lock 的线E将成功获取该锁定ƈq回。如果当前线E已l拥有该锁定Q此Ҏ立卌回。可以?isHeldByCurrentThread() ?getHoldCount() Ҏ来检查此情况是否发生?/p>

它提供了lock()ҎQ?br /> 如果该锁定没有被另一个线E保持,则获取该锁定q立卌回,锁定的保持计数讄?1?br /> 如果当前U程已经保持该锁定,则将保持计数?1Qƈ且该Ҏ立即q回?br /> 如果该锁定被另一个线E保持,则出于线E调度的目的Q禁用当前线E,q且在获得锁定之前,该线E将一直处于休眠状态,此时锁定保持计数被设|ؓ 1?/p>

最q在研究Java concurrent中关于Q务调度的实现ӞM延迟队列DelayQueue的一些代码,比如take()。该Ҏ的主要功能是从优先队列(PriorityQueueQ取Z个最应该执行的Q务(最优|Q如果该d的预订执行时间未刎ͼ则需要waitq段旉差。反之,如果旉CQ则q回该Q务。而offer()Ҏ是将一个Q务添加到该队列中?/p>

后来产生了一个疑问:如果最应该执行的Q务是一个小时后执行的,而此旉要提交一?0U后执行的Q务,会出C么状况?q是先看看take()的源代码Q?/p>

public E take() throws InterruptedException {

final ReentrantLock lock = this.lock;

lock.lockInterruptibly();

try {

for (;;) {

E first
= q.peek();

if (first == null) {

available.await();

}
else {

long delay = first.getDelay(TimeUnit.NANOSECONDS);

if (delay > 0) {

long tl = available.awaitNanos(delay);

}
else {

E x
= q.poll();

assert x != null;

if (q.size() != 0)

available.signalAll();
// wake up other takers

return x;

}

}

}

}
finally {

lock.unlock();

}

}

而以下是offer()的源代码:

public boolean offer(E e) {

final ReentrantLock lock = this.lock;

lock.lock();

try {

E first
= q.peek();

q.offer(e);

if (first == null || e.compareTo(first) < 0)

available.signalAll();

return true;

}
finally {

lock.unlock();

}

}

如代码所C,take()和offer()都是lock了重入锁。如果按照synchronized的思维Q用诸如synchronized(obj)的方法)Q这两个Ҏ是互斥的。回到刚才的疑问Qtake()Ҏ需要等?个小时才能返回,而offer()需要马上提交一?0U后q行的Q务,会不会一直等待take()q回后才能提交呢Q答案是否定的,通过~写验证代码也说明了q一炏V这让我寚w入锁有了更大的兴,它确实是一个无d的锁?/p>

下面的代码也许能说明问题Q运行了4个线E,每一ơ运行前打印lock的当前状态。运行后都要{待5U钟?/p>

public static void main(String[] args) throws InterruptedException {

final ExecutorService exec = Executors.newFixedThreadPool(4);

final ReentrantLock lock = new ReentrantLock();

final Condition con = lock.newCondition();

final int time = 5;

final Runnable add = new Runnable() {

public void run() {

System.out.println(
"Pre " + lock);

lock.lock();

try {

con.await(time, TimeUnit.SECONDS);

}
catch (InterruptedException e) {

e.printStackTrace();

}
finally {

System.out.println(
"Post " + lock.toString());

lock.unlock();

}

}

};

for(int index = 0; index < 4; index++)

exec.submit(add);

exec.shutdown();

}

 

q是它的输出Q?br /> Pre ReentrantLock@a59698[Unlocked]
Pre ReentrantLock@a59698[Unlocked]
Pre ReentrantLock@a59698[Unlocked]
Pre ReentrantLock@a59698[Unlocked]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-1]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-2]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-3]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-4]

每一个线E的锁状态都?#8220;Unlocked”,所以都可以q行。但在把con.awaitҎThread.sleep(5000)Ӟ输出变成了Q?br /> Pre ReentrantLock@a59698[Unlocked]
Pre ReentrantLock@a59698[Locked by thread pool-1-thread-1]
Pre ReentrantLock@a59698[Locked by thread pool-1-thread-1]
Pre ReentrantLock@a59698[Locked by thread pool-1-thread-1]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-1]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-2]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-3]
Post ReentrantLock@a59698[Locked by thread pool-1-thread-4]

以上的对比说明线E在{待?con.await)Q已l不在拥有(keepQ该锁了Q所以其他线E就可以获得重入锁了?br />

有必要会q头再看看Java官方的解释:“如果该锁定被另一个线E保持,则出于线E调度的目的Q禁用当前线E,q且在获得锁定之前,该线E将一直处于休眠状?#8221;。我对这里的“保持”的理解是指非wait状态外的所有状态,比如U程Sleep、for循环{一切有CPU参与的活动。一旦线E进入wait状态后Q它׃再keepq个锁了Q其他线E就可以获得该锁Q当该线E被唤醒Q触发信h者timeoutQ后Q就接着执行Q会重新“保持”锁,当然前提依然是其他线E已l不?#8220;保持”了该重入锁?/p>

ȝ一句话Q对于重入锁而言Q?lock"?keep"是两个不同的概念。lock了锁Q不一定keep锁,但keep了锁一定已llock了锁?/p>



rainman 2008-10-03 17:55 发表评论
]]>
Java 理论与实? 行的原?/title><link>http://www.tkk7.com/rainmanyang/articles/232204.html</link><dc:creator>rainman</dc:creator><author>rainman</author><pubDate>Fri, 03 Oct 2008 06:35:00 GMT</pubDate><guid>http://www.tkk7.com/rainmanyang/articles/232204.html</guid><wfw:comment>http://www.tkk7.com/rainmanyang/comments/232204.html</wfw:comment><comments>http://www.tkk7.com/rainmanyang/articles/232204.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/rainmanyang/comments/commentRss/232204.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/rainmanyang/services/trackbacks/232204.html</trackback:ping><description><![CDATA[<span style="font-family: verdana; font-size: 12px; line-height: 19px; "> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">十五q前Q多处理器系l是高度专用pȝQ要p数十万美元(大多数具有两个到四个处理器)。现在,多处理器pȝ很便宜,而且数量很多Q几乎每个主要微处理器都内置了多处理支持Q其中许多系l支持数十个或数百个处理器?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">要用多处理器系l的功能Q通常需要用多U程构造应用程序。但是正如Q何编写ƈ发应用程序的人可以告诉你的那P要获得好的硬件利用率Q只是简单地在多个线E中分割工作是不够的Q还必须保U程实大部分时间都在工作,而不是在{待更多的工作,或等待锁定共享数据结构?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="1.0"><span id="egauwmu" class="atitle" style="font-family: Arial, sans-serif; font-weight: bold; font-size: 18px; ">问题Q线E之间的协调</span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">如果U程之间 <em>?/em>需要协调,那么几乎没有d可以真正地ƈ行。以U程池ؓ例,其中执行的Q务通常怺独立。如果线E池利用公共工作队列Q则从工作队列中删除元素或向工作队列d元素的过E必LU程安全的,q且q意味着要协调对头、尾或节炚w链接指针所q行的访问。正是这U协调导致了所有问题?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="1.1"><span id="kuoakkq" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">标准ҎQ锁?/span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">?Java 语言中,协调对共享字D늚讉K的传l方法是使用同步Q确保完成对׃n字段的所有访问,同时h适当的锁定。通过同步Q可以确定(假设cȝ写正)h保护一l给定变量的锁定的所有线E都拥有对q些变量的独占访问权Qƈ且以后其他线E获得该锁定Ӟ可以看到对q些变量q行的更攏V弊端是如果锁定竞争太厉宻IU程常常在其他线E具有锁定时要求获得该锁定)Q会损害吞吐量,因ؓ竞争的同步非常昂c(Public Service AnnouncementQ对于现?JVM 而言Q无竞争的同步现在非怾宜?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">Z锁定的算法的另一个问题是Q如果gq具有锁定的U程Q因为页面错误、计划gq或其他意料之外的gq)Q则 <em>没有</em>要求获得该锁定的U程可以l箋q行?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">q可以用可变变量来以比同步更低的成本存储共享变量,但它们有局限性。虽然可以保证其他变量可以立即看到对可变变量的写入,但无法呈现原子操作的?修改-写顺序,q意味着Q比如说Q可变变量无法用来可靠地实现互斥Q互斥锁定)或计数器?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="1.1"><span id="ewimewm" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">使用锁定实现计数器和互斥</span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">假如开发线E安全的计数器类Q那么这暴?<code>get()</code>?<code>increment()</code> ?<code>decrement()</code> 操作。清?1 昄了如何用锁定(同步Q实现该cȝ例子。注意所有方法,甚至需要同?<code>get()</code>QɾcL为线E安全的c,从而确保没有Q何更C息丢失,所有线E都看到计数器的最新倹{?/p> <br /> <a name="listing1"><strong>清单 1. 同步的计数器c?/strong></a></span> <font face="verdana" size="3"><span style="font-size: 12px; line-height: 19px; "><strong> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> SynchronizedCounter {<br /> </span><span style="color: #0000FF; ">private</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> value;<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> getValue() { </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> value; }<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> increment() { </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">++</span><span style="color: #000000; ">value; }<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> decrement() { </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">--</span><span style="color: #000000; ">value; }<br /> }</span></div> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><font face=" font-weight: normal; "> </font></p> <font face=" font-weight: normal; "> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><code>increment()</code> ?<code>decrement()</code> 操作是原子的?修改-写操作,Z安全实现计数器,必须使用当前|qؓ其添加一个|或写出新|所有这些均视ؓ一Ҏ作,其他U程不能打断它。否则,如果两个U程试图同时执行增加Q操作的不幸交叉导致计数器只被实现了一ơ,而不是被实现两次。(注意Q通过使值实例变量成为可变变量ƈ不能可靠地完成这Ҏ作。)</p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">许多q发法中都昄了原子的?修改-写组合。清?2 中的代码实现了简单的互斥Q?<code>acquire()</code> Ҏ也是原子的读-修改-写操作。要获得互斥Q必ȝ保没有其他hh该互斥( <code>curOwner = Thread.currentThread()</code>Q,然后记录您拥有该互斥的事实( <code>curOwner = Thread.currentThread()</code>Q,所有这些其他U程不可能在中间出现以及修改 <code>curOwner field</code>?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="listing2"><strong>清单 2. 同步的互斥类</strong></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><strong> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> SynchronizedMutex {<br /> </span><span style="color: #0000FF; ">private</span><span style="color: #000000; "> Thread curOwner </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> acquire() </span><span style="color: #0000FF; ">throws</span><span style="color: #000000; "> InterruptedException {<br /> </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (Thread.interrupted()) </span><span style="color: #0000FF; ">throw</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> InterruptedException();<br /> </span><span style="color: #0000FF; ">while</span><span style="color: #000000; "> (curOwner </span><span style="color: #000000; ">!=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">) <br /> wait();<br /> curOwner </span><span style="color: #000000; ">=</span><span style="color: #000000; "> Thread.currentThread();<br /> }<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> release() {<br /> </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (curOwner </span><span style="color: #000000; ">==</span><span style="color: #000000; "> Thread.currentThread()) {<br /> curOwner </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">;<br /> notify();<br /> } </span><span style="color: #0000FF; ">else</span><span style="color: #000000; "><br /> </span><span style="color: #0000FF; ">throw</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> IllegalStateException(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">not owner of mutex</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /> }<br /> }</span></div> </strong></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">清单 1 中的计数器类可以可靠地工作,在竞争很或没有竞争旉可以很好地执行。然而,在竞争激烈时Q这大大损x能Q因?JVM 用了更多的时间来调度U程Q管理竞争和{待U程队列Q而实际工作(如增加计数器Q的旉却很。您可以回想 </span><a style="color: #5c81a7; "><span style="font-weight: normal;">上月专栏</span></a><span style="font-weight: normal;">中的图,该图昄了一旦多个线E用同步竞争一个内|监视器Q吞吐量如何大q度下降。虽然该专栏说明了新?</span><code><span style="font-weight: normal;">ReentrantLock</span></code><span style="font-weight: normal;"> cd何可以更可׾~地替代同步Q但是对于一些问题,q有更好的解x法?/span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="1.2"><span id="aacogwc" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-size: 15px; "><span style="font-weight: normal;">锁定问题</span></span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">使用锁定Q如果一个线E试图获取其他线E已l具有的锁定Q那么该U程被dQ直到该锁定可用。此Ҏh一些明昄~点Q其中包括当U程被阻塞来{待锁定Ӟ它无法进行其他Q何操作。如果阻塞的U程是高优先U的dQ那么该Ҏ可能造成非常不好的结果(UCؓ </span><span style="font-weight: normal;">优先U倒置</span><span style="font-weight: normal;">的危险)?/span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">使用锁定q有一些其他危险,如死锁(当以不一致的序获得多个锁定时会发生死锁Q。甚x有这U危险,锁定也仅是相对的_粒度协调机Ӟ同样非常适合理单操作,如增加计数器或更C斥拥有者。如果有更细_度的机制来可靠理对单独变量的q发更新Q则会更好一些;在大多数C处理器都有这U机制?/span></p> <strong><br /> </strong></font></strong></span><strong><font face=" font-weight: normal; "></font> <p> </p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><font face=" font-weight: normal; "><strong><br /> </strong> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tbody> <tr> <td style="line-height: 19px; "><img width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" height="1" alt="" /><br /> <img alt="" width="8" height="6" border="0" src="http://www.ibm.com/i/c.gif" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td style="line-height: 19px; "><img width="100%" height="4" src="http://www.ibm.com/i/c.gif" alt="" /><br /> <table border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td valign="middle" style="line-height: 19px; "><img width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" height="16" border="0" alt="" /><br /> </td> <td valign="top" align="right" style="line-height: 19px; "><a class="fbox" style="text-decoration: none; color: #5c81a7; font-family: verdana, nsimSun, arial, sans-serif; font-size: 12px; line-height: 13px; "><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> </font></p> <font face=" font-weight: normal; "> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="2.0"></a></p> <span style="font-size: 10pt; "> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="2.0"><span id="ewakeka" class="atitle" style="font-family: Arial, sans-serif; font-size: 18px; "><span style="font-weight: normal;">g同步原语</span></span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">如前所qͼ大多数现代处理器都包含对多处理的支持。当然这U支持包括多处理器可以共享外部设备和d存,同时它通常q包括对指opȝ的增加来支持多处理的Ҏ要求。特别是Q几乎每个现代处理器都有通过可以或L其他处理器的q发讉K的方式来更新׃n变量的指令?/span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="2.1"><span id="kkwiaqy" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-size: 15px; "><span style="font-weight: normal;">比较q交?(CAS)</span></span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">支持q发的第一个处理器提供原子的测试ƈ讄操作Q通常在单位上q行q项操作。现在的处理器(包括 Intel ?Sparc 处理器)使用的最通用的方法是实现名ؓ </span><em><span style="font-weight: normal;">比较q{?/span></em><span style="font-weight: normal;">?CAS 的原语。(?Intel 处理器中Q比较ƈ交换通过指o?cmpxchg pd实现。PowerPC 处理器有一对名?#8220;加蝲q保?#8221;?#8220;条g存储”的指令,它们实现相同的目圎ͼMIPS ?PowerPC 处理器相|除了W一个指令称?#8220;加蝲链接”。)</span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">CAS 操作包含三个操作?—?内存位置QVQ、预期原|AQ和新?B)。如果内存位|的g预期原值相匚wQ那么处理器会自动将该位|值更Cؓ新倹{否则,处理器不做Q何操作。无论哪U情况,它都会在 CAS 指o之前q回该位|的倹{(?CAS 的一些特D情况下仅q回 CAS 是否成功Q而不提取当前倹{)CAS 有效地说明了“我认Z|?V 应该包含?AQ如果包含该|则将 B 攑ֈq个位置Q否则,不要更改该位|,只告诉我q个位置现在的值即可?#8221;</span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">通常?CAS 用于同步的方式是从地址 V d?AQ执行多步计来获得新?BQ然后?CAS ?V 的g A 改ؓ B。如?V 处的值尚未同时更改,?CAS 操作成功?/span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><span style="font-weight: normal;">cM?CAS 的指令允许算法执行读-修改-写操作,而无需x其他线E同时修改变量,因ؓ如果其他U程修改变量Q那?CAS 会检它Qƈp|Q,法可以对该操作重新计算。清?3 说明?CAS 操作的行为(而不是性能特征Q,但是 CAS 的h值是它可以在g中实玎ͼq且是极轻量U的Q在大多数处理器中)Q?/span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="listing3"><span style="font-weight: normal;">清单 3. 说明比较q交换的行ؓQ而不是性能Q的代码</span></a></p> </span> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="listing3"><strong></strong></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><strong> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> SimulatedCAS {<br /> </span><span style="color: #0000FF; ">private</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> value;<br /> <br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> getValue() { </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> value; }<br /> <br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> compareAndSwap(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> expectedValue, </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> newValue) {<br /> </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> (value </span><span style="color: #000000; ">==</span><span style="color: #000000; "> expectedValue) <br /> value </span><span style="color: #000000; ">=</span><span style="color: #000000; "> newValue;<br /> </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> value;<br /> }<br /> }</span></div> </strong></p> </font> <p><span style="font-size: 12px; font-weight: normal; line-height: 19px; "> </span></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="2.2"><span id="wceiaqq" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">?CAS 实现计数?/span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">Z CAS 的ƈ发算法称?<em>无锁?/em>法Q因为线E不必再{待锁定Q有时称Z斥或关键部分Q这取决于线E^台的术语Q。无?CAS 操作成功q是p|Q在M一U情况中Q它都在可预知的旉内完成。如?CAS p|Q调用者可以重?CAS 操作或采取其他适合的操作。清?4 昄了重新编写的计数器类来?CAS 替代锁定Q?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "> </p> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> CasCounter {<br /> </span><span style="color: #0000FF; ">private</span><span style="color: #000000; "> SimulatedCAS value;<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> getValue() {<br /> </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> value.getValue();<br /> }<br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> increment() {<br /> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> oldValue </span><span style="color: #000000; ">=</span><span style="color: #000000; "> value.getValue();<br /> </span><span style="color: #0000FF; ">while</span><span style="color: #000000; "> (value.compareAndSwap(oldValue, oldValue </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">) </span><span style="color: #000000; ">!=</span><span style="color: #000000; "> oldValue)<br /> oldValue </span><span style="color: #000000; ">=</span><span style="color: #000000; "> value.getValue();<br /> </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> oldValue </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br /> }<br /> }</span></div> <p> </p> <p><span style="font-size: 12px; font-weight: normal; line-height: 19px; "> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="3.0"><span id="cakmyuk" class="atitle" style="font-family: Arial, sans-serif; font-weight: bold; font-size: 18px; ">无锁定且无等待算?/span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">如果每个U程在其他线EQ意gq(或甚臛_败)旉持l进行操作,可以说该算法是 <em>无等?/em>的。与此Ş成对比的是, <em>无锁?/em>法要求?#160;<em>某个</em>U程L执行操作。(无等待的另一U定义是保证每个U程在其有限的步骤中正确计算自己的操作,而不其他线E的操作、计时、交叉或速度。这一限制可以是系l中U程数的函数Q例如,如果?10 个线E,每个U程都执行一?#160;<code>CasCounter.increment()</code> 操作Q最坏的情况下,每个U程必重试最多九ơ,才能完成增加。)</p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">再过ȝ 15 q里Qh们已l对无等待且无锁定算法(也称?#160;<em>无阻塞算?/em>Q进行了大量研究Q许多h通用数据l构已经发现了无d法。无d法被广泛用于操作系l和 JVM U别Q进行诸如线E和q程调度{Q务。虽然它们的实现比较复杂Q但相对于基于锁定的备选算法,它们有许多优点:可以避免优先U倒置和死锁等危险Q竞争比较便宜,协调发生在更l的_度U别Q允许更高程度的q行机制{等?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="3.1"><span id="geikuca" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">原子变量c?/span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">?JDK 5.0 之前Q如果不使用本机代码Q就不能?Java 语言~写无等待、无锁定的算法。在 <code>java.util.concurrent.atomic</code> 包中d原子变量cM后,q种情况才发生了改变。所有原子变量类都公开比较q设|原语(与比较ƈ交换cMQ,q些原语都是使用q_上可用的最快本机结构(比较q交换、加载链?条g存储Q最坏的情况下是旋{锁)来实现的?#160;<code>java.util.concurrent.atomic</code> 包中提供了原子变量的 9 U风| <code>AtomicInteger</code>Q?#160;<code>AtomicLong</code>Q?#160;<code>AtomicReference</code>Q?#160;<code>AtomicBoolean</code>Q原子整型;长型Q引用;及原子标记引用和戌引用cȝ数组形式Q其原子地更C对|?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">原子变量cd以认为是 <code>volatile</code> 变量的泛化,它扩展了可变变量的概念,来支持原子条件的比较q设|更新。读取和写入原子变量与读取和写入对可变变量的讉Kh相同的存取语义?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">虽然原子变量c表面看h与清?1 中的 <code>SynchronizedCounter</code> 例子一P但相g是表面的。在表面之下Q原子变量的操作会变为^台提供的用于q发讉K的硬件原语,比如比较q交换?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="3.2"><span id="sgkewem" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">更细_度意味着更轻量</span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">调整h竞争的ƈ发应用程序的可׾~性的通用技术是降低使用的锁定对象的_度Q希望更多的锁定h从竞争变Z竞争。从锁定转换为原子变量可以获得相同的l果Q通过切换为更l粒度的协调机制Q竞争的操作更,从而提高了吞吐量?/p> <table align="right" border="0" cellspacing="0" cellpadding="0" width="40%"> <tbody> <tr> <td width="10" style="line-height: 19px; "><img alt="" height="1" width="10" src="http://www.ibm.com/i/c.gif" /></td> <td style="line-height: 19px; "> <table border="1" cellspacing="0" cellpadding="5" width="100%"> <tbody> <tr> <td bgcolor="#eeeeee" style="line-height: 19px; "><a name="sidebar1"><strong>ABA 问题</strong></a><br /> 因ؓ在更?V 之前QCAS 主要询问“V 的值是否仍?A”Q所以在W一ơ读?V 以及?V 执行 CAS 操作之前Q如果将g A 改ؓ BQ然后再改回 AQ会使基?CAS 的算法؜乱。在q种情况下,CAS 操作会成功,但是在一些情况下Q结果可能不是您所预期的。(注意Q?#160;<a style="color: #5c81a7; ">清单 1</a> ?#160;<a style="color: #5c81a7; ">清单 2</a> 中的计数器和互斥例子不存在这个问题,但不是所有算法都q样。)q类问题UCؓ <em>ABA 问题</em>Q通常通过标记或版本~号与要q行 CAS 操作的每个值相兌Qƈ原子地更新值和标记Q来处理q类问题?#160;<code>AtomicStampedReference</code> cL持这U方法?/td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="3.3"><span id="muwgqoo" class="smalltitle" style="font-family: arial, nsimsun, sans-serif; font-weight: bold; font-size: 15px; ">java.util.concurrent 中的原子变量</span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">无论是直接的q是间接的,几乎 <code>java.util.concurrent</code> 包中的所有类都用原子变量,而不使用同步。类?code>ConcurrentLinkedQueue</code> 的类也用原子变量直接实现无{待法Q而类?#160;<code>ConcurrentHashMap</code> 的类使用 <code>ReentrantLock</code> 在需要时q行锁定。然后, <code>ReentrantLock</code> 使用原子变量来维护等待锁定的U程队列?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">如果没有 JDK 5.0 中的 JVM 改进Q将无法构造这些类Q这些改q暴露了Q向cdQ而不是用LQ接口来讉KgU的同步原语。然后,java.util.concurrent 中的原子变量cd其他cd用户cd开q些功能?/p> <br /> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tbody> <tr> <td style="line-height: 19px; "><img width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" height="1" alt="" /><br /> <img alt="" width="8" height="6" border="0" src="http://www.ibm.com/i/c.gif" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td style="line-height: 19px; "><img width="100%" height="4" src="http://www.ibm.com/i/c.gif" alt="" /><br /> <table border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td valign="middle" style="line-height: 19px; "><img width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" height="16" border="0" alt="" /><br /> </td> <td valign="top" align="right" style="line-height: 19px; "><a class="fbox" style="text-decoration: none; color: #5c81a7; font-family: verdana, nsimSun, arial, sans-serif; font-size: 12px; line-height: 13px; "><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="4.0"><span id="guosksy" class="atitle" style="font-family: Arial, sans-serif; font-weight: bold; font-size: 18px; ">使用原子变量获得更高的吞吐量</span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a style="color: #5c81a7; ">上月</a>Q我介绍?#160;<code>ReentrantLock</code> 如何相对于同步提供可伸羃性优势,以及构造通过伪随机数生成器模拟旋转骰子的单、高竞争CZ基准。我向您昄了通过同步?#160;<code>ReentrantLock</code> 和公q?#160;<code>ReentrantLock</code> 来进行协调的实现Qƈ昄了结果。本月,我将向该基准d其他实现Q?#160;<code>AtomicLong</code> 更新 PRNG 状态的实现?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">清单 5 昄了用同步的 PRNG 实现和?CAS 备选实现。注意,要在循环中执?CASQ因为它可能会失败一ơ或多次才能获得成功Q?CAS 的代码Lq样?/p> <br /> <a name="listing5"><strong>清单 5. 使用同步和原子变量实现线E安?PRNG</strong></a><br /> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tbody> <tr> <td class="code-outline" style="line-height: 19px; background-color: #eeeeee; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; "> <pre class="displaycode" style="margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 11px; "> public class PseudoRandomUsingSynch implements PseudoRandom { private int seed; public PseudoRandomUsingSynch(int s) { seed = s; } public synchronized int nextInt(int n) { int s = seed; seed = Util.calculateNext(seed); return s % n; } } public class PseudoRandomUsingAtomic implements PseudoRandom { private final AtomicInteger seed; public PseudoRandomUsingAtomic(int s) { seed = new AtomicInteger(s); } public int nextInt(int n) { for (;;) { int s = seed.get(); int nexts = Util.calculateNext(s); if (seed.compareAndSet(s, nexts)) return s % n; } } } </pre> </td> </tr> </tbody> </table> <br /> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">下面?1 和图 2 中的图与上月那些囄|只是为基于原子的Ҏ多添加了一行。这些图昄了在 8-way Ultrasparc3 和单处理?Pentium 4 上用不同数量线E的随机发生的吞吐量Q以每秒转数为单位)。测试中的线E数不是真实的;q些U程所表现的竞争比通常多得多,所以它们以比实际程序中低得多的U程数显CZ <code>ReentrantLock</code> 与原子变量之间的q。您看刎ͼ虽然 <code>ReentrantLock</code> 拥有比同步更多的优点Q但相对?#160;<code>ReentrantLock</code>Q原子变量提供了其他改进。(因ؓ在每个工作单元中完成的工作很,所以下囑֏能无法完全地说明?ReentrantLock 相比Q原子变量具有哪些可伸羃性优炏V)</p> <br /> <a name="fig1"><strong>?1. 8-way Ultrasparc3 中同步、ReentrantLock、公q?Lock ?AtomicLong 的基准吞吐量</strong></a><br /> <img alt="8-way Ultrasparc3 吞吐? height="332" src="http://www.ibm.com/developerworks/cn/java/j-jtp11234/RngThroughput.gif" width="550" /> <br /> <br /> <a name="fig2"><strong>?2. 单处理器 Pentium 4 中的同步、ReentrantLock、公q?Lock ?AtomicLong 的基准吞吐量</strong></a><br /> <img alt="Uniprocessor Pentium4 吞吐? height="328" src="http://www.ibm.com/developerworks/cn/java/j-jtp11234/RngThroughputUni.gif" width="551" /> <br /> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">大多数用户都不太可能使用原子变量自己开发无d法 ?他们更可能?#160;<code>java.util.concurrent</code> 中提供的版本Q如 <code>ConcurrentLinkedQueue</code>。但是万一您想知道Ҏ以前 JDK 中的相类似的功能Q这些类的性能是如何改q的Q可以用通过原子变量cd开的细_度、硬件别的q发原语?/p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">开发h员可以直接将原子变量用作׃n计数器、序L成器和其他独立共享变量的高性能替代Q否则必通过同步保护q些变量?/p> <br /> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tbody> <tr> <td style="line-height: 19px; "><img width="100%" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" height="1" alt="" /><br /> <img alt="" width="8" height="6" border="0" src="http://www.ibm.com/i/c.gif" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td style="line-height: 19px; "><img width="100%" height="4" src="http://www.ibm.com/i/c.gif" alt="" /><br /> <table border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td valign="middle" style="line-height: 19px; "><img width="16" src="http://www.ibm.com/i/v14/icons/u_bold.gif" height="16" border="0" alt="" /><br /> </td> <td valign="top" align="right" style="line-height: 19px; "><a class="fbox" style="text-decoration: none; color: #5c81a7; font-family: verdana, nsimSun, arial, sans-serif; font-size: 12px; line-height: 13px; "><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; "><a name="5.0"><span id="awicock" class="atitle" style="font-family: Arial, sans-serif; font-weight: bold; font-size: 18px; ">l束?/span></a></p> <p style="padding-bottom: 8px; padding-top: 5px; margin-top: 0px; margin-bottom: 0px; ">JDK 5.0 是开发高性能q发cȝ巨大q步。通过内部公开新的低协调原语Q和提供一l公共原子变量类Q现在用 Java 语言开发无{待、无锁定法首次变ؓ可行。然后, <code>java.util.concurrent</code> 中的cd于这些低U原子变量工h建,为它们提供比以前执行怼功能的类更显著的可׾~性优炏V虽然您可能永远不会直接使用原子变量Q还是应该ؓ它们的存在而欢呹{?/p> </span></p> </strong></font> <img src ="http://www.tkk7.com/rainmanyang/aggbug/232204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/rainmanyang/" target="_blank">rainman</a> 2008-10-03 14:35 <a href="http://www.tkk7.com/rainmanyang/articles/232204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://ryhjled.com" target="_blank">Ѿþþþþ</a>| <a href="http://4466n.com" target="_blank">91Ƶ</a>| <a href="http://89kino.com" target="_blank">þþþŷղAV</a>| <a href="http://whspmd.com" target="_blank">ҹƷ߹ۿ</a>| <a href="http://gkhnf.com" target="_blank">ĻۺϾþۺ </a>| <a href="http://55118885.com" target="_blank">ƷþþþþþѼձ</a>| <a href="http://43caopen.com" target="_blank">ۺϼ޵һҳ</a>| <a href="http://7272004.com" target="_blank">츾ëXXXX</a>| <a href="http://9988u.com" target="_blank">þþƷһ</a>| <a href="http://dslygc.com" target="_blank">ԻƵ߿Ƭ</a>| <a href="http://4922000.com" target="_blank">ձһ</a>| <a href="http://628669.com" target="_blank">߹ۿƵ</a>| <a href="http://959901cc.com" target="_blank">þþþþһ</a>| <a href="http://szmazida.com" target="_blank">պĻһ</a>| <a href="http://aplus178.com" target="_blank">޾ƷƵ</a>| <a href="http://0755haoma.com" target="_blank">ëƬֻ߿</a>| <a href="http://bying100.com" target="_blank">߿Ƭ˳Ƶ</a>| <a href="http://njchxf.com" target="_blank">˳ɵӰվ</a>| <a href="http://52ku6.com" target="_blank">þþƷav鶹</a>| <a href="http://ytshdiping.com" target="_blank">Ļwww˳</a>| <a href="http://81am.com" target="_blank">99ƷƵ߹ۿ</a>| <a href="http://51cga.com" target="_blank">ŷһëƬѿ</a>| <a href="http://xvwenyue.com" target="_blank">޹Ʒһ</a>| <a href="http://www-333346.com" target="_blank">ۺ뾫Ʒһ</a>| <a href="http://ddxsrd.com" target="_blank">ѿƷ3aƵƵ</a>| <a href="http://vvv75.com" target="_blank">˶wwwҹվ</a>| <a href="http://bbscqz.com" target="_blank">ۺϳ</a>| <a href="http://367316.com" target="_blank">þþƷ99Ʒ</a>| <a href="http://www676617.com" target="_blank">޾Ʒ뾫ƷmV߹ۿ</a>| <a href="http://szzdjl.com" target="_blank">ƷþþþӰԺ</a>| <a href="http://bbyy7.com" target="_blank">߿ƬvѹۿƵ777</a>| <a href="http://wwwbu610.com" target="_blank">йڵëƬѸ</a>| <a href="http://fenxiangceo.com" target="_blank">ձ޸߹ۿ</a>| <a href="http://600c63.com" target="_blank">a߹ۿ</a>| <a href="http://mtripmall.com" target="_blank">avɫ</a>| <a href="http://53ggk.com" target="_blank">ĻþþƷˮ </a>| <a href="http://020iws.com" target="_blank">պƷһ </a>| <a href="http://456qqq.com" target="_blank">Ļ</a>| <a href="http://lfhuanxin.com" target="_blank">AƬѹۿ</a>| <a href="http://dqmovie.com" target="_blank">һѻɫƬ</a>| <a href="http://xiaomaomi8.com" target="_blank">Ůһ18</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>