ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>
private String id;
private String name;
private String broker;
private String date;
private String body;
//get/set
public String toString(){
return "ã€ç¼–å·äØ“:"+id+",òq¿å‘Šåç§°ä¸?"+name+",代ç†å•†äØ“:"+broker+",å‘布日期ä¸?"+date+",内容ä¸?"+body+"ã€?/span>";
}
}
//调用ä»ÕdŠ¡¾c?/p>
//ä¸Õd‡½æ•?/p>
在过åŽÈš„电脑都已å?/span>CPUä½œäØ“ä¸»è¦çš„å¤„ç†æ–¹å¼ï¼Œæ— 论æ˜?/span>PC或者是æœåŠ¡å™¨éƒ½æ˜¯å¦‚æ¤ã€‚ç³»¾lŸè°ƒç”¨æŸä¸€ä¸ªæ—¶åˆÕdªèƒ½æœ‰ä¸€ä¸ªçº¿½E‹è¿è¡Œã€‚当然这当ä¸é‡‡ç”¨äº†æ¯”较多的ç–ç•¥æ¥åšæ—¶é—´ç‰‡è½®è¯¢ã€‚é€šè¿‡ä¸æ–çš„è°ƒåº¦åˆ‡æ¢æ¥˜q行¾U¿ç¨‹˜q行åQŒè€Œè¿™¿Uæ–¹å¼å°±å«åšòq¶å‘åQ?/span>concurrentåQ‰ã€?/span>
éšç€å·¥è‰ºæ°´åã^çš„é€æ¸æå‡åQ?/span>CPUçš„æŠ€æœ¯ä¹Ÿåœ¨ä¸æ–增˜q›ã€‚å› æ¤åœ¨å¦‚今多个CPUå·²ç»ä¸æ˜¯ä»€ä¹ˆç‰¹åˆ«çš„åQŒè€Œå¤§å®¶å¸¸å¸æ€»¥SMPçš„æ–¹å¼æ¥å½¢å®¹å¤šä¸ªCPUæ¥å¤„ç†ä¸¤ä¸ªæˆ–者两个以上的¾U¿ç¨‹˜q行方弞®Þq§°ä¸ºåƈ行(parallelåQ‰ã€?/span>
¾l§æ‰¿ThreadåQŒå®žçŽ?/span>start()æ–ÒŽ³•
è¦å®žçŽ°çº¿½E‹è¿è¡Œï¼ŒJAVA䏿œ‰ä¸¤ç§æ–¹å¼åQ?/span>
实现RunnableåQŒç„¶åŽå†ä¼ 递给Thread实例
注æ„åQšçº¿½E‹å¯¹è±¡å’Œ¾U¿ç¨‹æ˜¯ä¸¤ä¸ªæˆªç„¶ä¸åŒçš„æ¦‚念ã€?/span>
¾U¿ç¨‹å¯¹è±¡æ˜?/span>JVM产生的一个普通的Objectåç±»
¾U¿ç¨‹æ˜?/span>CPU分酾l™è¿™ä¸ªå¯¹è±¡çš„一个è¿è¡Œè¿‡½E?/span>
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
Thread.sleep(3000);
mt.start();
}
}
当线½E‹å¯¹è±?/span>mt˜q行完æˆå?/span>,我们让主¾U¿ç¨‹ä¼‘æ¯ä¸€ä¸‹ï¼Œç„¶åŽæˆ‘们冿¬¡åœ¨è¿™ä¸ªçº¿½E‹å¯¹è±¡ä¸Šå¯åЍ¾U¿ç¨‹.¾l“果我们看到åQ?/span>
Exception in thread "main" java.lang.IllegalThreadStateException
æ ÒŽœ¬åŽŸå› æ˜¯åœ¨ä»¥ä¸‹æºä»£ç 䏿‰‘Ö‡ºåQ?/span>
public synchronized void start() {
if (started)
throw new IllegalThreadStateException();
started = true;
group.add(this);
start0();
}
一ä¸?/span>Thread的实例一旦调ç”?/span>start()æ–ÒŽ³•åQŒè¿™ä¸ªå®žä¾‹çš„startedæ ‡è®°ž®±æ ‡è®îCØ“trueåQŒäº‹å®žä¸ä¸ç®¡˜q™ä¸ª¾U¿ç¨‹åŽæ¥æœ‰æ²¡æœ‰æ‰§è¡Œåˆ°åº•,åªè¦è°ƒç”¨äº†ä¸€‹Æ?/span>start()ž®±å†ä¹Ÿæ²¡æœ‰æœºä¼šè¿è¡Œäº†åQŒè¿™æ„味ç€åQ?/span>
ã€é€šè¿‡Thread实例çš?/span>start()åQŒä¸€ä¸?/span>Thread的实例åªèƒ½äñ”生一个线½E‹ã€?/span>
当一个线½E‹å¯¹è±¡è°ƒç”?/span>interrupt()æ–ÒŽ³•åQŒå®ƒå¯¹åº”的线½E‹åÆˆæ²¡æœ‰è¢«ä¸æ–ï¼Œåªæ˜¯æ”¹å˜äº†å®ƒçš„䏿–状æ€ã€‚ä‹É当剾U¿ç¨‹çš„状æ€å˜ä»¥ä¸æ–状æ€ï¼Œå¦‚果没有其它影å“åQŒçº¿½E‹è¿˜ä¼šè‡ªå·Þq‘ô¾læ‰§è¡Œã€‚åªæœ‰å½“¾U¿ç¨‹æ‰§è¡Œåˆ?/span>sleepåQ?/span>waitåQ?/span>join½{‰æ–¹æ³•æ—¶åQŒæˆ–è€…è‡ªå·±æ£€æŸ¥ä¸æ–状æ€è€ŒæŠ›å‡ºå¼‚常的情况下,¾U¿ç¨‹æ‰ä¼šæŠ›å‡ºå¼‚常ã€?/span>
join()æ–ÒŽ³•åQŒæ£å¦‚第一节所a€åQŒåœ¨ä¸€ä¸ªçº¿½E‹å¯¹è±¡ä¸Šè°ƒç”¨joinæ–ÒŽ³•åQŒæ˜¯å½“剾U¿ç¨‹½{‰å¾…˜q™ä¸ª¾U¿ç¨‹å¯¹è±¡å¯¹åº”的线½E‹ç»“æ?/span>
例如åQšæœ‰ä¸¤ä¸ªå·¥ä½œåQŒå·¥ä½?/span>Aè¦è€—æ—¶10¿U’é’ŸåQŒå·¥ä½?/span>Bè¦è€—æ—¶10¿U’或更多。我们在½E‹åºä¸å…ˆç”Ÿæˆä¸€ä¸ªçº¿½E‹åŽ»åšå·¥ä½?/span>BåQŒç„¶åŽåšå·¥ä½œAã€?/span>
new B().start();//åšå·¥ä½?/span>B
A();//åšå·¥ä½?/span>A
工作A完æˆåŽï¼Œä¸‹é¢è¦ç‰å¾…å·¥ä½?/span>B的结果楘q›è¡Œå¤„ç†ã€‚如果工ä½?/span>B˜q˜æ²¡æœ‰å®Œæˆæˆ‘ž®×ƒ¸èƒ½è¿›è¡Œä¸‹é¢çš„工作CåQŒæ‰€ä»¥ï¼š
B b = new B();
b.start();//åšå·¥ä½?/span>B
A();//åšå·¥ä½?/span>A
b.join();//½{‰å·¥ä½?/span>B完æˆ.
C();//¾l§ç®‹å·¥ä½œC
原则åQšã€?/span>join是测试其它工作状æ€çš„唯一æ£ç¡®æ–ÒŽ³•ã€?/span>
yield()æ–ÒŽ³•也是¾cÀL–¹æ³•,åªåœ¨å½“剾U¿ç¨‹ä¸Šè°ƒç”¨ï¼Œç†ç”±åŒä¸ŠåQŒå®ƒä¸ÀL˜¯è®©å½“å‰çº¿½E‹æ”¾å¼ƒæœ¬‹Æ¡åˆ†é…到的时间片åQŒè°ƒç”¨è¿™ä¸ªæ–¹æ³•ä¸ä¼šæé«˜ä“Qä½•æ•ˆçŽ‡ï¼Œåªæ˜¯é™ä½Žäº?/span>CPUçš„æ€Õd‘¨æœŸä¸Šé¢ä»‹¾lçš„¾U¿ç¨‹ä¸€äº›æ–¹æ³•,åŸÞZºŽ(基础½‹?/span>)而言åªèƒ½½Ž€å•æåŠã€‚以åŽå…·ä½“åº”ç”¨ä¸æˆ‘会¾l“åˆå®žä¾‹è¯¦ç»†è®ø™¿°ã€?/span>
原则åQšã€ä¸æ˜¯éžå¸¸å¿…è¦çš„æƒ…况下,没有ç†ç”±è°ƒç”¨å®ƒã€?/span>
首先明确一点他们的属于普通对象方法,òq‰™žæ˜¯çº¿½E‹å¯¹è±¡æ–¹æ³•;其次它们åªèƒ½åœ¨åŒæ¥æ–¹æ³•ä¸è°ƒç”¨ã€‚线½E‹è¦æƒŒ™°ƒç”¨ä¸€ä¸ªå¯¹è±¡çš„wait()æ–ÒŽ³•ž®Þp¦å…ˆèŽ·å¾—è¯¥å¯¹è±¡çš„ç›‘è§†é”,而一旦调ç”?/span>wait()åŽåˆç«‹å³é‡Šæ”¾è¯¥é”ã€?/span>
多个¾U¿ç¨‹åŒæ—¶æ“作æŸä¸€å¯¹è±¡æ—Óž¼Œä¸€ä¸ªçº¿½E‹å¯¹è¯¥å¯¹è±¡çš„æ“ä½œå¯èƒ½ä¼šæ”¹å˜å…¶çжæ€ï¼Œè€Œè¯¥çжæ€ä¼šå½±å“å¦ä¸€¾U¿ç¨‹å¯¹è¯¥å¯¹è±¡çš„真æ£ç»“æžœã€?/span>
把一个å•å…ƒå£°æ˜ŽäØ“synchornized,ž®±å¯ä»¥è®©åœ¨åŒä¸€æ—‰™—´åªæœ‰ä¸€ä¸ªçº¿½E‹æ“作该æ–ÒŽ³•ã€‚ä½œä¸ø™®°å¿†å¯ä»¥æŠŠsynchronized看作是一个é”。但是我们è¦ç†è§£é”是被动的,˜q˜æ˜¯ä¸ÕdŠ¨çš„å‘¢åQŸæ¢è€Œè¨€ä¹‹å®ƒåˆ°åº•é”什么了åQŸé”è°äº†åQ?/span>
例如åQ?/span>
synchronized(obj){
//todo…
}
å¦‚æžœä»£ç ˜q行到æ¤å¤„,synchronized首先获å–obj傿•°å¯¹è±¡çš„é”åQŒè‹¥æ²¡æœ‰èŽ·å–¾U¿ç¨‹åªèƒ½½{‰å¾…åQŒå¦‚果多个线½E‹è¿è¡Œåˆ°˜q™åªèƒ½æœ‰ä¸€ä¸ªçº¿½E‹èŽ·å?/span>objçš„é”åQŒç„¶åŽå†æ‰§è¡Œ{}ä¸çš„代ç ã€‚å› æ?/span>obj作用范围ä¸åŒåQŒæŽ§åˆ¶ç¨‹åºä¹Ÿä¸åŒã€?/span>
å¦‚æžœä¸€ä¸ªæ–¹æ³•å£°æ˜ŽäØ“synchornized的,则ç‰åŒäºŽæŠŠåœ¨ä¸ÞZ¸ªæ–ÒŽ³•上调ç”?/span>synchornized(this)ã€?/span>
å¦‚æžœä¸€ä¸ªé™æ€æ–¹æ³•被声明ä¸?/span>synchornizedåQŒåˆ™½{‰åŒäºŽæŠŠåœ¨äؓ个方法上调用synchornized(¾c?/span>.class)
è¦è®©ä¸€ä¸ªçº¿½E‹å¾—åˆ°çœŸæ£æ„ä¹‰çš„åœæ¢åQŒéœ€è¦äº†è§£å½“å‰çš„¾U¿ç¨‹åœ¨å¹²ä»€ä¹ˆï¼Œå¦‚æžœ¾U¿ç¨‹å½“剿²¡æœ‰åšä»€ä¹ˆï¼Œé‚£ç«‹åˆ»è®©å¯ÒŽ–¹é€€å‡ºï¼Œå½“然是没有ä“Q何问题,但是如果å¯ÒŽ–¹æ£åœ¨æ‰‹å¤´èµ¶å·¥åQŒé‚£ž®±å¿…™å»è®©ä»–åœæ¢ï¼Œç„¶åŽæ”¶æ‹¾ŒD‹å±€ã€‚å› æ¤ï¼Œé¦–先需è¦äº†è§£æ¥éª¤ï¼š
1. æ£å¸¸˜q行åQ?/span>
2. 处熾l“æŸå‰çš„工作,也就是准备结æŸï¼›
3. ¾l“æŸé€€å‡ºã€?/span>
æ³¨ï¼šä»¥ä¸Šéƒ¨åˆ†æ¦‚æ‹¬å‡ø™‡ªæŸä½ç‰›äh大哥的笔讎ͼŒ¾l常拜读他的åšå®¢åœ?/span>java.nioåŒ…ä¸æˆ‘们å¯ä»¥ç›´æŽ¥æ¥æ“作相对应çš?/span>API了。å¯ä»¥è®©javaæ›´åŠ æ–¹ä¾¿çš„ç›´æŽ¥æŽ§åˆ¶å’Œ˜q用¾~“å†²åŒºã€‚ç¼“å†²åŒºæœ‰å‡ ä¸ªéœ€è¦äº†è§£çš„特定概念需è¦è¯¦ž®½æ¥è§£é‡ŠåQŒæ‰èƒ½æ›´å¥½çš„çŸ¥é“æˆ‘们下é¢ä¸€äº›åˆ—需è¦é’ˆå¯¹çš„问题实质ã€?/span>
定w‡åQ?/span>capacityåQ‰ï¼š™å‘Öæ€ä¹‰ž®±æ˜¯è¡¨ç¤º¾~“冲åŒÞZ¸å¯ä»¥ä¿å˜å¤šå°‘æ•°æ®åQ?/span>
æžé™åQ?/span>limitåQ‰ï¼š¾~“冲åŒÞZ¸çš„当剿•°æ®ç»ˆ¾l“点。丘q‡å®ƒæ˜¯å¯ä»¥åŠ¨æ€æ”¹å˜çš„åQŒè¿™æ ·åšçš„好处也是充分利用é‡ç”¨æ€§ï¼›
ä½ç½®(position)åQšè¿™ä¸ªä¹Ÿå¥½ç†è§£ï¼Œå…¶å®žž®±æ˜¯æŒ‡æ˜Žä¸‹ä¸€ä¸ªéœ€è¦è¯»å†™æ•°æ®çš„ä½ç½®ã€?/span>
上é¢ä¸Šä¸ªå…³ç³»˜q˜å¯ä»¥å…·ä½“用囄¡¤ºçš„æ–¹å¼æ¥è¡¨è¾¾æ•´ä½“概念åQŒå¦‚下图所½Cºï¼š
l clear()åQšé¦–先把æžé™è®„¡½®ä¸ºå®¹é‡ï¼Œå†è€…å°±æ˜¯éœ€è¦æŠŠä½ç½®è®„¡½®ä¸?/span>0åQ?/span>
l flip()åQšæŠŠæžé™è®„¡½®ä¸ÞZ½¾|®åŒºåQŒå†è€…å°±æ˜¯éœ€è¦æŠŠä½ç½®è®„¡½®ä¸?/span>0åQ?/span>
l rewind()åQšä¸æ”¹å˜æžé™åQŒä¸˜q‡è¿˜æ˜¯éœ€è¦æŠŠä½ç½®è®„¡½®ä¸?/span>0ã€?/span>
最为最基础的缓冲区ByteBufferåQŒå®ƒå˜æ”¾çš„æ•°æ®å•元是å—节。首先è¦å¼ø™°ƒçš„æ˜¯ByteBuffer没有æä¾›å…¬å¼€çš„æž„é€ æ–¹æ³•ï¼Œåªæ˜¯æä¾›äº†ä¸¤ä¸ªé™æ€çš„工厂æ–ÒŽ³•ã€?/span>
l allocate(int capacity)åQšè¿”回一ä¸?/span>ByteBuffer对象åQŒå‚数表½Cºç¼“冲区定w‡å¤§å°ã€?/span>
l allocateDirect (int capacity)åQšè¿”回一ä¸?/span>ByteBuffer对象åQŒå‚æ•îC¹Ÿæ˜¯ä¸€æ ¯‚¡¨½Cºç¼“冲区定w‡å¤§å°ã€?/span>
åœ¨è¿™é‡Œéœ€è¦æ³¨æ„的是在使用两者的时候需è¦ç‰¹åˆ«å°å¿ƒï¼ŒallocateDirectå’Œå½“å‰æ“作系¾lŸè”¾pÈš„éžå¸¸ç´§å¯†åQŒå®ƒç‰‰|¶‰åˆîC‹Éç”?/span>native method的方法,大家知é“一旦本地方法就是需è¦è€ƒè™‘调用dllåQˆåЍæ€é“¾æŽ¥åº“åQ‰è¿™ä¸ªæ—¶å€™åŸºæœ¬ä¹Ÿž®±å¤±åŽÖMº†JAVAè¯è¨€çš„特性,a€å¤–之æ„对于耗资æºéžå¸¸å¤§ã€‚所以如果考虑到当å‰ä‹É用的¾~“å˜åŒºæ¯”较庞大而且是一个长期驻留ä‹É用的åQŒè¿™ä¸ªæ—¶å€™å¯ä»¥è€ƒè™‘使用它ã€?/span>
Rmi自从JDK1.1ž®±å·²¾l出çŽîCº†ã€‚è€Œå¯¹äºŽäØ“ä»€ä¹ˆåœ¨JAVA的世界里需è¦ä¸€ä¸ªè¿™æ ?/span> æ€æƒ³ç†å¿µž®±éœ€è¦çœ‹ä¸‹ï¼šRMI问世由æ¥ã€‚其实真æ£åœ¨å›½å†…使用到它的比较少åQŒä¸˜q‡åœ¨å‰äº›òq´æ¯”较ç«çš?/span>EJBž®±æ˜¯åœ¨å®ƒçš„基¼‹€ä¸Šè¿›ä¸€æ¥æ·±åŒ–的。从本质上æ¥è®?/span>RMI的兴èµäh£æ˜¯äؓ了设计分布å¼çš„客戗÷€æœåС噍¾l“构需求而应˜q而生的,而它的这¿U?/span>B/S¾l“æž„æ€æƒ³èƒ½å¦å’Œæˆ‘们通常çš?/span>JAVA¾~–ç¨‹æ›´åŠ è´´åˆ‡å‘¢ï¼Ÿa€å¤–之æ„就是能å¦è®©˜q™ç§åˆ†å¸ƒå¼çš„状æ€åšåˆ°æ›´åР逿˜ŽåQŒä½œä¸ºå¼€å‘äh员åªéœ€è¦æŒ‰ç…§å¾€å¸æ€¸€æ ·å¼€å?/span>JAVA应用½E‹åºä¸€æ äh¥å¼€å‘分布å¼çš„结构。那现在的问题是如何æ¥åˆ’òqŒ™¿™ä¸ªé¿`沟呢åQŸé¦–先我们æ¥åˆ†æžä¸‹åœ¨JAVAä¸–ç•Œé‡Œå®ƒçš„ä¸€äº›ç‰¹ç‚¹å› ç´ ï¼š
l JAVA使用垃圾攉™›†¼‹®å®šå¯¹è±¡çš„生命周期ã€?/span>
l JAVAä½¿ç”¨å¼‚å¸¸å¤„ç†æ¥æŠ¥å‘Šè¿è¡ŒæœŸé—´çš„错误。这里就è¦å’Œæˆ‘们¾|‘络通讯ä¸çš„异常相蔾p»è“væ¥äº†ã€‚在B/S¾l“构的网¾lœä½“¾pÖM¸æˆ‘们的这¿U错误性是éžå¸¸å¸¸è§çš„ã€?/span>
l JAVA¾~–写的对象通过调用æ–ÒŽ³•æ¥è°ƒç”¨ã€‚由于网¾lœé€šè®¯æŠŠæˆ‘们的客户与æœåŠ¡å™¨ä¹‹é—´é˜»éš”å¼€äº†ã€‚ä½†æ˜¯ä»£ç†çš„一¿Uæ–¹å¼å¯ä»¥å¾ˆå¥½çš„æä¾›ä¸€¿Uè¿™æ ïLš„å‡è±¡åQŒè®©å¼€å‘äh员或者ä‹É用者都感觉是在本地调用ã€?/span>
l JAVAå…许一¿U高¾U§çš„使用¾cÕdŠ è½½å™¨åQ?/span>CLassLoaderåQ‰æœºåˆ¶æä¾›ç³»¾lŸç±»è·¯å¾„䏿²¡æœ‰çš„¾c…R€‚è¿™è¯ä»€ä¹ˆæ„æ€ï¼Ÿ
上é¢è¯´åˆ°äº†åˆ†å¸ƒå¼çš„æ–¹å¼å’Œæˆ‘们çš?/span>JAVAä¸å¦‚何更好的划åã^˜q™ä¸ªé¸¿æ²ŸåQŒéœ€è¦å…·å¤‡çš„特质ã€?/span>
那这里我们æ¥çœ‹çœ‹æˆ‘们所谓的RMI到底跟我们普通的JAVAåQˆæˆ–者说JavaBeanåQ‰å˜åœ¨ä¸€äº›ä»€ä¹ˆæ ·çš„差异:
l RMI˜qœç¨‹å¼‚常åQ?/span>Remote ExceptionåQ‰ï¼šåœ¨ä¸Šé¢æˆ‘们也æåˆ°äº†ä¸€ä¸ªç½‘¾lœé€šè®¯éš‘Ö…æœ‰ä¸€äº›æ— è®ºæ˜¯è½¯äšg¾U§åˆ«çš„还是硬件çñ”别的异常现象åQŒæœ‰æ—¶å€™è¿™äº›å¼‚常或许是一¿Uæ— æ³•é¢„çŸ¥çš„¾l“果。让我们开å‘äh¾~˜å¦‚何æ¥å›žæº¯˜q™ç§å¼‚常信æ¯åQŒè¿™ä¸ªæ˜¯æˆ‘们开å‘äh员è¦å…›_¿ƒçš„ã€‚å› æ¤åœ¨è°ƒç”¨˜qœç¨‹å¯¹è±¡çš„æ–¹æ³•䏿ˆ‘们必须在远½E‹æŽ¥å£ä¸åQˆæŽ¥å£æ˜¯ä¸€¿Uè§„èŒƒçš„æ ‡å‡†è¡ŒäØ“åQ‰æ‰€ä»¥åœ¨è°ƒç”¨çš„这个方法体上需è¦ç¾å注明:java.rmi,RemoteException.ã€‚è¿™ä¹Ÿå°±æ³¨æ˜Žäº†æ¤æ–ÒŽ³•是需è¦è°ƒç”¨è¿œ½E‹å¯¹è±¡çš„ã€?/span>
l å€ég¼ é€?/span> åQšå½“æŠŠå¯¹è±¡ä½œä¸ºå‚æ•îC¼ 递给一个普通的JAVA对象æ–ÒŽ³•调用æ—Óž¼Œåªæ˜¯ä¼ 递该对象çš?strong>引用。请注愘q™é‡Œè°ˆåˆ°çš„æ˜¯å¯¹è±¡çš?#8220;引用”一è¯ï¼Œå¦‚æžœåœ¨ä¿®æ”¹è¯¥å‚æ•°çš„æ—¶å€™ï¼Œæ˜¯ç›´æŽ¥ä¿®æ”¹åŽŸå§‹å¯¹è±¡ã€‚å®ƒòq¶ä¸æ˜¯æ‰€è°“的一个对象的备䆾或者说拯‚´åQˆè¯´ç™½äº†ž®±æ˜¯åœ¨æœ¬JVM内å˜ä¸çš„对象åQ‰ã€‚但是如果说使用的是RMI对象åQŒåˆ™å®Œå…¨æ˜¯æ‹·è´çš„。这与普通对象有ç€é²œæ˜Žçš„å¯¹æ¯”ã€‚ä¹Ÿæ£æ˜¯ç”׃ºŽ˜q™ç§æ‹¯‚´çš„èµ„æºæ¶ˆè€—é€ å°±äº†ä¸‹é¢è¦è¯´åˆ°çš„æ€§èƒ½¾~ºå¤±äº†ã€?/span>
l 调用开销åQšå‡¡æ˜¯ç»˜q‡ç½‘¾lœé€šè®¯ç†è®ºä¸Šæ¥è¯´éƒ½æ˜¯ä¸€¿U资æºçš„æ¶ˆè€—。它需è¦é€šè¿‡¾~–组与å¾~–组方å¼ä¸æ–解枾cÕd¯¹è±¡ã€‚而且RMI本èín也是一¿U需è¦è¿”回值的一个过½E‹å®šä¹‰ã€?/span>
l 安全æ€?/span>åQšä¸€è°ˆåˆ°¾|‘络通讯势必会说到如何ä¿è¯å®‰å…¨çš„˜q›è¡Œã€?/span>
åœ¨å¼€å§‹è¿›è¡ŒåŽŸç†æ¢³ç†ä¹‹å‰æˆ‘们需è¦å®šä¹‰æ¸…æ¥šå‡ ä¸ªåè¯ã€‚对于这些åè¯çš„ç†è§£å½±å“到åŽçš„æ·±å…¥è¿›è¡Œã€?/span>
1. StubåQˆå˜æ ¹ï¼Œæœ‰äº›ä¹¦ä¸Šä¹Ÿç¿»è¯‘æˆåQšæ¡©åŸºåœ¨EJB的相关书¾c丞®¤äؓ体现˜q™ä¸ªæ„æ€ï¼‰åQ?/span>
˜q™é‡Œä¸¾ä¾‹è¯´æ˜Ž˜q™ä¸ªæ¦‚å¿µèµøP¼ˆæˆ–许ä¸å¤Ÿæ°å½“åQ‰ã€‚ä¾‹å¦‚å¤§å®¶å› å…¬å‡ºå·®åŽåQŒéƒ½æœ‰å˜åœ¨ä¸€äº›æŠ¥é”€çš„呼œ¨æˆ–者说ž®ç¥¨ã€‚å¯¹äºŽä½ å½“å‰æ‰‹å¤´æ‰€æ‹¿åˆ°çš„呼œ¨åÆˆä¸æ˜¯ä¸€ä¸ªå”¯ä¸€çš„ï¼Œå®ƒåŒæ—¶è¿˜åœ¨ä½ å‘生消费的地ç‚ÒŽœ‰ä¸€ä¸ªå¤åîCšgåQŒè€Œè¿™ä¸ªå¤åîCšgž®±æ˜¯æ‰€è°“çš„å˜æ ¹ã€‚ä½†æ˜¯è¿™ä¸ªå˜æ ¹ä¸Šòq¶æ²¡æœ‰å¾ˆå¤šæ˜Ž¾l†çš„æè¿°åQŒåªæ˜¯æœ‰ä¸€ä¸ªå¤§æ¦‚的金é¢å®šä¹‰ã€‚它把很多的¾l†èŠ‚è´¹ç”¨éƒ½å¿½ç•¥äº†ã€‚æ‰€ä»¥è¿™ä¸ªä¹Ÿæ˜¯æˆ‘ä»¬è¯´çš„å˜æ ¹å®šä¹‰ã€‚而在我们RMIçš„å˜æ ¹å®šä¹‰å°±æ˜¯ä‹É用了˜q™æ ·ä¸€ä¸ªç†è§£ï¼šåœ¨ä¸Ž˜qœç¨‹å‘生通讯调用æ—Óž¼ŒæŠŠé€šè®¯è°ƒç”¨çš„æ‰€æœ‰ç»†èŠ‚éƒ½é€šè¿‡å¯¹è±¡çš„å°è£…åÅžå¼ç»™éšè—在åŽç«¯ã€‚这本èínž®Þq¬¦å?/span>OOADçš„æ„æ€ç†å¿üc€‚而暴露出æ¥çš„ž®±æ˜¯æˆ‘ä»¬çš„æŽ¥å£æ–¹å¼ï¼Œè€Œè¿™¿UæŽ¥å£æ–¹å¼åˆå’ŒæœåŠ¡å™¨çš„å¯¹è±¡å…·æœ‰ç›¸åŒçš„æŽ¥å£åQˆè¿™é‡Œå°±å’Œæˆ‘们å‰é¢ä‹Dä¾‹è¯´çš„æŠ¥é”€å•æ®è”系上了åQŒæŠ¥é”€å•æ®çš„å˜æ ¹ä¸çŸ¥é“会有一个什么åÅžå¼å‘ç”Ÿå…·ä½“é—®é¢˜ï¼Œè€Œä½ æ‰‹æ‰§çš„å‘¼œ¨å…·ä½“就需è¦åˆ°è´µå…¬å¸åŽ»æŠ¥é”€è´¹ç”¨åQŒè€Œè¿™é‡Œçš„å…¬å¸è´¢åŠ¡å¤„å°±æ˜¯æ‰€è°“çš„æœåŠ¡å™¨ç«¯åQŒå®ƒæ‰æ˜¯çœŸæ£òq²å®žè´¨æ€§é—®é¢˜çš„ã€‚ï¼‰å› æ¤ä½œäؓ开å‘äh员åªéœ€è¦æŠŠ¾_‘ÖŠ›é›†ä¸åœ¨ä¸šåŠ¡é—®é¢˜çš„è§£å†³ä¸Šï¼Œè€Œä¸éœ€è¦è€ƒè™‘夿‚的分布å¼è®¡ç®—。所有这些问题都交给RMIåŽÖM¸€ä¸€å¤„ç†ã€?/span>
2. Skeleton(一些书¾˜»è¯‘å«éª¨æžÓž¼Œä¹Ÿå«¾l“æž„ä½?/span>)åQšå®ƒçš„内部就是真æ£å°è£…了一个类的åÅžæˆè°ƒç”¨ä½“现机制。包括我们熟知的ServerSocket创å¾ã€æŽ¥å—ã€ç›‘å¬ã€å¤„ç†ç‰ã€?/span>
3. Mashalling(¾~–组)åQšåœ¨å†…å˜ä¸çš„å¯¹è±¡è½¬æ¢æˆå—节æµåQŒä»¥ä¾¿èƒ½å¤Ÿé€šè¿‡¾|‘络˜qžæŽ¥ä¼ 输ã€?/span>
4. Unmashalling(åç¼–¾l?/span>)åQšåœ¨å†…å˜ä¸æŠŠå—节‹¹è{æ¢æˆå¯¹è±¡åQŒä»¥ä¾¿æœ¬åœ°åŒ–调用ã€?/span>
5. Serialization(åºåˆ—åŒ?/span>)åQšç¼–¾l„ä¸ä½¿ç”¨åˆ°çš„æŠ€æœ¯å«åºåˆ—化ã€?/span>
6. Deserializationg(ååºåˆ—化)åQšå¾~–组ä¸ä‹É用到的技术å«ååºåˆ—化ã€?/span>
既然我们知é“stubä¸»è¦æ˜¯ä»¥æŽ¥å£çš„æ–¹å¼æ¥æš´éœ²ä½“现åQŒè€?/span>stubä¸»è¦ ä¹Ÿæ˜¯ä»¥ä»£ç†çš„æ–¹å¼æ¥å…·ä½“实施。那åœ?/span>RMIä¸çš„˜q™ç§æŽ¥å£æœ‰å“ªäº›ç‰¹æ€§å‘¢åQŸï¼ˆRemote InterfaceåQ?/span>
1) 必须扩展åQ?/span>extendsåQ?/span>java.rmi.Remote接å£åQŒå› 䏸™¿œ½E‹æŽ¥å£åƈä¸åŒ…å«ä“Qä½•ä¸€ä¸ªæ–¹æ³•ï¼Œè€Œæ˜¯ä½œäØ“ä¸€ä¸ªæ ‡è®°å‡ºçŽ?/span>åQŒå®ƒž®±æ˜¯éœ€è¦å‘Šè¯?/span>JVMåœ?/span>RunTime的时候哪些是常规对象åQŒå“ªäº›å±žäºŽè¿œ½E‹å¯¹è±¡ã€‚通过˜q™ç§æ ‡è¯†çš„定义能è®?/span>JVM了解¾cÖM¸å“ªäº›æ–ÒŽ³•需è¦ç¼–¾l„,通过了编¾l„çš„æ–¹å¼æ‰èƒ½é€šè¿‡¾|‘络åºåˆ—化的调用åQ?/span>
2) 接å£å¿…é¡»ä¸?/span>publicåQˆå…¬å…±ï¼‰åQŒå®ƒçš„好处ä¸a€è€Œå–»çš„——能够方便的让所有äh员æ¥è°ƒç”¨ã€?/span>
3) æŽ¥å£æ–ÒŽ³•˜q˜éœ€è¦ä»¥å¼‚常抛出åQˆä¾‹å¦‚:RemoteExceptionåQ‰ï¼Œè‡³äºŽå®ƒçš„用处我们在å‰é¢ä¹Ÿæåˆ°˜q™é‡Œž®×ƒ¸å†å¤˜qŽÍ¼›
4) 在调用一个远½E‹å¯¹è±¡æœŸé—ß_¼ˆ˜q行期间åQ‰ï¼Œæ–ÒŽ³•çš„å‚æ•°å’Œ˜q”回值都è¦å¿…™åÀL˜¯å¯åºåˆ—åŒ–çš„ã€‚è‡³äºŽäØ“ä»€ä¹ˆéœ€è¦è¿™ä¹ˆåšåQŸè¿™é‡Œçš„¾~˜ç”±ä¸ç”¨å¤šè¯´å¤§å®¶ä¹Ÿåº”该清楚了解ã€?/span>
既然我们知é“stub所åšçš„事情是一个简å•的代ç†è½¬å‘动作åQŒé‚£æˆ‘们真æ£è¦åšçš„对象就在æœåŠ¡ç«¯æ¥åšäº†ã€‚对于ä‹É用简å•çš„RMI我们直接åŽÀLŒ‡å®šï¼Œä½†æ˜¯å¾€å¾€ä¸€æ—¦ä‹É用了RMI对象ž®±å˜åœ¨éžå¸¸å¤šçš„远½E‹æ–¹æ³•调用,˜q™ä¸ªæ—¶å€™æœåŠ¡å™¨ç«¯å¯¹äºŽè¿™ä¹ˆå¤šçš„è°ƒç”¨å¦‚ä½•æ¥åˆ¤åˆ«æˆ–者说识别呢?˜q™é‡Œž®Þp¦è¯´åˆ°çš„æ˜¯å¯¹äºŽRMI实现它会创å¾ä¸€ä¸ªæ ‡è¯†ç¬¦åQŒä»¥ä¾¿ä»¥åŽçš„stubå¯ä»¥è°ƒç”¨è½¬å‘¾l™æœåŠ¡å™¨å¯¹è±¡ä½¿ç”¨äº†ï¼Œè€Œè¿™¿Uæ–¹å¼æˆ‘ä»¬é€šå¸¸å«æœåС噍RMI的注册机制。言外之æ„就是让æœåŠ¡å™¨ç«¯çš„å¯¹è±¡æ³¨å†Œåœ¨RMI机制ä¸ï¼Œç„¶åŽå¯ä»¥å¯¼å‡ºè®©ä»ŠåŽçš„stub按需æ¥è°ƒç”¨ã€‚é‚£å®ƒåˆæ˜¯å¦‚何åšåˆ°è¿™¿Uæ–¹å¼çš„呢?对于RMIæ¥è¯´æœ‰ä¸¤¿Uæ–¹å¼å¯ä»¥è¾¾åˆ°è¿™¿U效果:
a) 直接使用UnicastRemoteObjectçš„é™æ€æ–¹æ³•:exportObjectåQ?/span>
b) ¾l§æ‰¿UnicastRemoteObject¾cÕdˆ™¾~ºçœçš„æž„é€ å‡½æ•?/span>exportObjectã€?/span>
现在大家åˆä¼šé—®ä»–ä»¬ä¹‹é—´åˆæœ‰ä»€ä¹ˆåŒºåˆ«å‘¢åQŸæˆ‘该ä‹É用哪¿Uæ–¹å¼æ¥åšå‘¢åQŒè¿™ä¸æ˜¯å¾ˆéš¾åšæŠ‰æ‹©å—åQŸä»Žä¸€èˆ¬åº”用场景æ¥è¯´åŒºåˆ«åÆˆä¸æ˜¯å¾ˆå¤§åQŒä½†æ˜¯ï¼Œ˜q™é‡Œè¯´äº†“但是”哦,呵呵。大家知é“ç‘ôæ‰¿çš„æ–¹å¼æ˜¯æŠŠçˆ¶ç±»æ‰€å…·å¤‡çš„æ‰€æœ‰ç‰¹è´¨éƒ½å¯ä»¥å®Œå¥½æ— æŸçš„ç‘ô承到åç±»ä¸è€Œå¯¹äºŽç±»çš„æ€»è€å¤§åQ?/span>Objectæ¥è¯´é‡Œé¢æœ‰ï¼šequals()ã€?/span>hashCode()ã€?/span>toString()½{‰æ–¹æ³•。这是个什么概念呢åQŸæ„æ€å°±æ˜¯è¯´å¦‚果对于本地化的调用åQŒä»–们两个的æ–ÒŽ³•åQ?/span>a,båQ‰åŸºæœ¬åŒºåˆ«ä¸æ˜¯å¾ˆå¤§ã€‚但是我们这里强调的RMI如果是一¿U分布å¼çš„特定场景,具备使用哈希表这¿U特性就昑־—ž®¤äØ“é‡è¦äº†ã€?/span>
刚æ‰è¯´äº†æœåŠ¡ç«¯é‡‡ç”¨ä»€ä¹ˆæ–¹æ³•è¡Œä¸ºå¯¼å‡ºå¯¹è±¡çš„ã€‚é‚£çŽ°åœ¨å¯¼å‡ºåŽçš„对象åˆå¯¹åº”会å‘生什么情况呢åQ?/span>
首先被导出的对象被分é…ä¸€ä¸ªæ ‡è¯†ç¬¦åQŒè¿™ä¸ªæ ‡è¯†ç¬¦è¢«ä¿å˜äØ“åQ?/span>java.rmi.server.ObjID对象ä¸åƈ被放åˆîC¸€ä¸ªå¯¹è±¡åˆ—è¡¨ä¸æˆ–è€…ä¸€ä¸ªæ˜ ž®„ä¸ã€‚而这里的ID是一个关键å—åQŒè€Œè¿œ½E‹å¯¹è±¡åˆ™æ˜¯å®ƒçš„一个å€û|¼ˆè¯´åˆ°˜q™å¤§å®¶æœ‰æ²¡æœ‰è§‰å¾—它原ç†éžå¸¸åƒHashMap的特质呢åQŸæ²¡é”™ï¼Œå…¶å®žž®±æ˜¯ä½¿ç”¨äº†å®ƒçš„特性)åQŒè¿™æ ·å®ƒž®±å¯ä»¥å¾ˆå¥½çš„å’Œå‰é¢åˆ›å»ºçš„stubæ²Ÿé€šã€‚å¦‚æžœè°ƒç”¨äº†é™æ€æ–¹æ³?/span>UnicastRemoteObject.export(Remote …)åQ?/span>RMIž®×ƒ¼šé€‰æ‹©ä»ÀL„一个端å£å·åQŒä½†˜q™åªæ˜¯ç¬¬ä¸€è°ƒç”¨å‘生在éšåŽçš„exportObjectæ¯æ¬¡è°ƒç”¨éƒ½æŠŠ˜qœç¨‹å¯¹è±¡å¯¼å‡ºåˆ°è¯¥˜qœç¨‹å¯¹è±¡½W¬ä¸€è¢«å¯¼å‡ºæ—¶ä½¿ç”¨çš„端å£å·ã€‚è¿™æ ·å°±ä¸ä¼šäº§ç”Ÿæ··äØ•åQŒä¼šæŠŠå…ˆå‰ä¸€ä¸€å¯¼å‡ºçš„对象全部放入到列表ä¸ã€‚当然如果采用的是指定端å£çš„åQŒåˆ™æŒ‰ç…§å¯¹åº”昄¡¤ºçš„调用方å¼ä‹É用。这里ç¨ä½œå¼ºè°ƒçš„æ˜¯ä¸€ä¸ªç«¯å£å¯ä»¥å¯¼å‡ÞZ“Qæ„æ•°ç›®çš„对象ã€?/span>
åQˆå¾…¾l?/span>……åQ?/span>多数¾|‘络¾~–程库ä¸åQˆä»¥JAVAä¸ÞZ¸»æ¥è¯´æ˜Žï¼‰åQŒåœ¨JAVAòq›_°ä¸ä¸€æ ïLš„æä¾›äº†è¿™äº›å…ƒç´ 。而作为é¢å‘连接åè®®æ¥è¯´ä‹É用的是套接å—åQ?/span>SocketåQ‰è¿›è¡Œäº†æ›´è¿›ä¸€æ¥çš„æŠ½è±¡æè¿°ã€‚一般我们在JAVA的网¾lœç¼–½E‹ä¸éƒ½è§‰å¾—在使用套接å—è¿™å—相å¯ÒŽ–¹ä¾¿ï¼Œå®ƒä¸éœ€è¦ä½ åŽÀL›´å¤šçš„了解æ“作¾pÈ»Ÿçš„细节以åŠç¡¬ä»¶çš„ä¼ é€’å¤„ç†æ–¹å¼ã€?/span>TCP/IP的所有细节之处都得到了套接å—çš„å°è£…ä‹É用,让程åºå‘˜å…Ïx³¨åˆîC¸šåС层é¢çš„处ç†ã€?/span>
对象是一¿U抽象æ€ç»´ç‰©è´¨åQŒå¯¹äºŽè®¡½Ž—机æ¥è¯´å®ƒåªå¯ÒŽ•°å—电路的å˜å‚¨æ–¹å¼èƒ½å¤ŸåŠ ä»¥è¯†åˆ«è€Œä¸”åœ¨ç½‘¾lœä¼ 输当ä¸ä¹Ÿæ˜¯ä¸€¿Uä¿¡å·é‡åQŒè€Œè¿™ä¸€åˆ‡åªæœ‰ä‹É用å—èŠ‚æµæ–¹å¼ä¼ è¾“æ‰æ˜¯çœŸæ£éœ€è¦åšåˆ°çš„。所以在本地ä¸ÀLœºä¸Žè¿œ½E‹æœåŠ¡å™¨çš„é€šè®¯ä¼ è¾“ž®±åœ¨å¯¹è±¡ä¸Žå—节æµä¹‹é—´ä¸æ–ç›æ€º’è½¬åŒ–æ‰æ˜¯æˆ‘们真æ£éœ€è¦çš„人性物质与机器所需è¦çš„。(有点墨迹了,切入整体åQ‰æ€ÖM½“æ¥è¯´ž®±æ˜¯éœ€è¦ä¸¤¿Uæ–¹å¼æ¥è®¤å®š˜q™ç§ä¼ è¾“è¡ŒäØ“åQšç¼–¾l„(MarshallingåQ‰ä¸Žåç¼–¾l„(UnmarshallingåQ‰ã€‚è€Œè¿™ä¸€åˆ‡çš„æ‰‹æ®µæ–¹å¼æ‰æ˜¯é€šè¿‡åQšåºåˆ—化åQ?/span>SerialiazableåQ‰ä¸Žååºåˆ—化的方å¼ä¸æ–完æˆã€‚如下图所½Cºï¼š
图:对象到å—节å†åˆ°å¯¹è±¡çš„è½¬æ¢ å¯¹äºŽæ•°æ®çš„ä¼ è¾“æœ¬è´¨å°±æ˜¯ä¸Šå›¾è¯´æ˜Žçš„ã€‚é‚£æˆ‘ä»¬ä¸€èˆ¬æ˜¯å¦‚ä½•ä½¿ç”¨å¥—æŽ¥å—æ¥æž„é€ æˆ‘ä»¬è¿™ä¸€è¡ŒäØ“å‘¢ï¼Ÿå¯¹äºŽ˜q™é‡Œå¼ø™°ƒçš„ä¸»è¦æ˜¯ä¸€¿U大致方法说明,所以åªèƒ½ä»¥éƒ¨åˆ†ä»£ç æ¥è¯´æ˜Žå®¢æˆïL«¯æ€Žä¹ˆæ¥å‘é€è¿™ä¸ªè¯·æ±‚ã€?/span> Socket socket=new Socket("http://www.wgh.com.cn",8888); OutputStream out=socket.getOutputStream(); ObjectOutputStream obj=new ObjectOutputStream(out); obj.writeObject(object); InputStream in=socket.getInputStream(); ObjectInputStream objIn=new ObjectInputStream(in); Object objFoo=(Object)objIn.readObject(); //todo ˜q™é‡Œž®±æ˜¯å…·ä½“˜q›è¡Œæ“ä½œçš„ç›¸å…³ä¼ å€¼å‚æ•°å¤„ç†äº†… obj.close(); objIn.close(); socket.close(); 而作为æœåŠ¡å™¨çš„æŽ¥æ”¶æ–¹åˆ™æŠŠä»¥ä¸Šæ•°æ®åšä¸€ä¸ªé€†è{相å处熞®±å¯ä»¥ã€‚峿œåŠ¡å™¨éœ€è¦è¯»å–å‘é€è¿‡æ¥çš„对象数æ®åQŒæœ€¾lˆå¾—到结果。现在å‡è®¾è¿˜æ˜¯ä¸€ä¸ªç”šè‡Ïx›´å¤šè¿™æ ïLš„对象处ç†åQŒæˆ‘们åˆè¦å¤„ç†å’Œä»¥ä¸Šä»£ç å·®ä¸å¤šçš„˜q‡ç¨‹ã€‚好åQŒåˆ°˜q™é‡Œæˆ‘们坿›¾æƒ›_ˆ°éšùN“没有一¿U办法把˜q™äº›˜q‡å¤šçš„é‡å¤è¿‡½E‹åšä¸€ä¸ªé€šç”¨çš„æ–¹å¼æ¥æä¾›å—ï¼Ÿæˆ‘å¦‚æžœä¸æƒ›_Ž»åšè¿™äº›ç¹æ‚的对象处ç†å¯ä»¥å—?比如åQŒæˆ‘想直接得刎ͼš //å…¶ä¸clientObjectjiž®±æ˜¯ä»Žå®¢æˆïL«¯ä¼ 输˜q‡æ¥çš„副本; MyObject myObject=server.getFoo(clientObject); ˜q™æ ·ž®Þpƒ½è®©æˆ‘ä»¬æŠŠåº•å±‚çš„é‚£äº›åºžæ‚æ•°æ®è{æ¢èƒ½å¤Ÿé€æ˜Žž®è£…èµäh¥å‘¢ï¼Ÿæ—¢ç„¶˜q™ä¸ªé—®é¢˜ä¸€¾læå‡ºï¼Œé‚£å°±æ„味ç€è‚¯å®šæœ‰å¾ˆå¤šç±»ä¼¼çš„需求。技术永˜qœéƒ½æ˜¯åœ¨éœ€æ±‚çš„æå‡ºåº”è¿è€Œç”Ÿçš„ã€‚ä¸Šé¢æå‡ºçš„éœ€æ±‚å°±æ˜¯æˆ‘ä»¬è¦è®¨è®ºçš„,既然我们æƒÏxŠŠä¸€äº›å¥—æŽ¥å—çš„é‡å¤å¤„ç†è¿‡½E‹æ¥ä¸ªå°è£…清ç†ï¼Œé‚£éœ€è¦é¢å¯¹çš„问题是什么呢åQ?/span> 1. 能够把所有的相åŒå¤„熘q‡ç¨‹å…¨éƒ¨éƒ½ç§»å…¥åˆ°æœåŠ¡ç«¯å‘¢åQ?/span> 2. 对于客户端æ¥è¯´èƒ½å¦åªé¢„留接å£è¡Œäؓ呢? 3. æŠŠè¿‡å¤šçš„å¤æ‚处熘q‡ç¨‹å®Œå–„çš„åšä¸ªå°è£…? 4. 如果以上˜q‡ç¨‹èƒ½å¤Ÿå½¢æˆåQŒé‚£å®¢æˆ·ç«¯åˆæ˜¯å¦‚何办到å¯ä»¥è¿žæŽ¥åˆ°æœåŠ¡å™¨ç«¯çš„ç»„ä»¶è¡Œä¸ºå‘¢åQ?/span> 既然能够把é‡åˆ°çš„问题æå‡ºç„¶åŽæ€È»“出æ¥ä¹Ÿå°±æ„å‘³ç€æˆ‘们需è¦åŽ»è§£å†³å®ƒã€‚ä¸çŸ¥é“是妘q?/span> 记得设计模å¼ä¸æœ‰ä¸€ä¸ªå«åQšä»£ç†æ¨¡å¼ï¼Ÿæ²¡é”™åQŒå°±æ˜¯è¿™ä¸ªä»£ç†æ¨¡å¼å¼€å§‹æˆ‘们的æè¿°ã€‚ä»£ç†æ˜¯ä¸€ä¸ªå®žçŽ°ç»™å®šæŽ¥å£çš„对象åQŒä½†æ˜¯ä¸ç›´æŽ¥åŽÀL‰§è¡Œä»£ç 结果,而是代表其他一些对象执行实际计½Ž—的对象。怎么ç†è§£˜q™ä¸ªè¯å‘¢åQŸä‹D例说åQŒå¦‚今很多城市都有ç«è½¦ç¥¨æˆ–者飞机票的代售点åQŒè¿™é‡Œçš„代售点其实就是采用了一¿Uä»£ç†æœºåˆ¶ã€‚我们想买æŸå¤©çš„ç«èžRæˆ–è€…é£žæœºç¥¨æœ‰æ—¶å€™åÆˆä¸éœ€è¦åˆ°ç«èžR站或者飞机票的æ€È‚¹åŽ»è´ä¹°ç¥¨åQŒè€Œæ˜¯æ‰¾ä¸€ä¸ªä½ 最˜q‘的代售点去è´ä¹°ã€‚代售点ž®±æ˜¯èµ·åˆ°ä¸€ä¸ªä¸é—´æ¡¥æ¢çš„作用åQŒè‡³äºŽä¹°¼œ¨ähå‘˜æ— éœ€å…›_¿ƒä»–们如何去订è´ï¼Œ˜q™äº›å…·ä½“的动作都ç”׃»–们内部去处ç†åQŒä½ åªå…³å¿ƒæœ€¾lˆæ˜¯å¦æœ‰ä½ 需è¦çš„¼œ¨å°±è¡Œã€‚知é“è¿™ä¸ªåŽŸç†æŽ¥ä¸‹æ¥ž®±å¥½ç†è§£å¾ˆå¤šäº†ï¼Œæˆ‘们最好以¾cÕd›¾çš„æ–¹å¼æ¥è¯´æ˜Ž˜q™ä¸ªä»£ç†çš„æœºåˆÓž¼Œå¦‚图所½Cºï¼š
到这里如果还觉得抽象åQŒæ²¡å…³ç³»æŽ¥ä¸‹æ¥æˆ‘ä»¥æ›´åŠ è„“åˆ‡çš„å®žä¾‹æ¥ç»“åˆç±»å›„¡š„方弾l™å‡ºå¯¹åº”çš„å‚照说明。å‡å¦‚我们把上é¢çš?/span>proxy模å¼å†åšä¸ªæ·±å…¥çš„æŽ¢è®¨å‰–æžåQˆç»“åˆä¸Šé¢è¯´çš„客æˆïL«¯å‘é€å‚æ•îC½œä¸ø™¯·æ±‚å’Œæå‡ºçš„问题综˜qŽÍ¼‰ã€‚大安™ƒ½çŸ¥é“ä¸€ä¸ªæŽ¥å£æ˜¯èƒ½å¤Ÿåœ¨å®‰å…¨ç”šè‡›_œ¨æ‰©å±•上能够帮助我们éžå¸¸å¤§çš„功能。作为客æˆïL«¯æœ€ä¸ºå¸Œæœ›çš„ž®±æ˜¯åªå…³å¿ƒæˆ‘们需è¦çš„傿•°åQˆæˆ–者å˜é‡ï¼‰ã€è¿”回å€û|¼Œè€Œå®ƒå¦‚何而æ¥åQŒåšäº†å“ªäº›å…·ä½“å·¥ä½œè¿™äº›éƒ½ä¸æ˜¯å®¢æˆ·ç«¯å…³å¿ƒçš„ã€?/span>Ok,现在¾l“åˆæˆ‘ä»¬è¯´çš„æŽ¥å£æ–¹å¼åQŒç¡®å®žå¯ä»¥è§£å†Œ™¿™ä¸ªé—®é¢˜ï¼ˆæŽ¥å£çš„简å•化åQŒæ²¡æœ‰å…·ä½“实玎ͼ‰åQŒä½†æ˜¯ä½ å¯èƒ½ä¼šé—®åQ?/span> 1. 既然接å£å¦‚æ¤½Ž€å•ï¼Œé‚£å‚æ•°åˆæ˜¯å¦‚ä½•ä¼ é€’è¿‡åŽÈš„呢? 2. æœåŠ¡ç«¯åˆå¦‚ä½•çŸ¥é“æˆ‘è¦çš„æ˜¯ä»€ä¹ˆå‘¢åQ?/span> 带ç€é—®é¢˜æˆ‘们æ¥è§£å†Œ™¿™ä¸ªé—®é¢˜ï¼Œå½“然也是大家所兛_¿ƒçš„问题了。现在开始è¦å¯¹äºŽä¸Šé¢çš?/span>proxy模å¼åšä¸ªæ·±å…¥å‰–æžäº†ã€‚我们先æ¥çœ‹ä¸€ä¸?/span>proxyæ¨¡å¼æ¼”å˜çš„过½E‹çš„囄¡¤ºåQ?
图:RMIæ ¸å¿ƒ¾l“æž„ 我们å¯ä»¥ä»Žå›¾½Cºçœ‹å‡ÞZ»Žä¼ 统çš?/span>proxy模å¼å˜åŒ–åˆîC¸€ä¸ªå˜åŒ–çš„¾l“构有什么ä¸åŒå‘¢åQŸå¯¹äºŽå…ˆå‰æˆ‘们æå‡ºçš„两个问题ž®±å¯ä»¥å¾ˆå¥½çš„åšå‡ºè§£é‡Šäº†ï¼š n 既然接å£å¦‚æ¤½Ž€å•ï¼Œé‚£å‚æ•°åˆæ˜¯å¦‚ä½•ä¼ é€’è¿‡åŽÈš„呢? A:既然是对客户端åªå¼€æŽ¥å£æš´éœ²åQŒé‚£ä¹ˆæˆ‘们是ž®±éœ€è¦ä¸€ä¸ªåŽå°çš„socketæ¥ä¼ 输接å£ä¸å·²ç»å®šä¹‰å¥½çš„傿•°åQŒé€šè¿‡å‚数的编¾l„(åºåˆ—化)方å¼è¯äh±‚到远½E‹æœåŠ¡ä¸ŠåŽÕd“应处ç†ã€‚这当ä¸è¦æ±‚定义到对æ–ÒŽœåŠ¡çš„æœåŠ¡å称和端å£å·ã€‚(˜q™é‡Œä¹Ÿå°±æ˜¯æˆ‘们最先æåˆ°çš„那段代ç 了) n æœåŠ¡ç«¯åˆå¦‚ä½•çŸ¥é“æˆ‘è¦çš„æ˜¯ä»€ä¹ˆå‘¢åQ?/span> A:ok,既然客户端是通过socketæ¥å‘逿•°æ®ï¼Œé‚£åŠ¿å¿…ä¸€å®šéœ€è¦?/span>ServerSocketæ¥åš˜q™ä¸ªå“应的接收处ç†äº†ã€‚é—®é¢˜æ˜¯ä¼ è¿‡æ¥çš„傿•°å¦‚何与我们的业务实现¾cÕd…³è”上呢?所以这个也ž®±æ˜¯skeletonçš„èŒè´£æ‰€åœ¨äº†åQŒåœ¨skeletonçš„å°è£…处ç†ä¸åQˆå¯åŠ¨ä¸ž®±æŠŠå“应实现¾cÈ»™åµŒå…¥åQŒèšåˆå®žçŽ°ç±»åQ‰ï¼Œç„¶åŽé€šè¿‡¾c»è{æ¢å¤„ç†å’ŒåŒšw…å¤„ç†æ¥å¾—到需è¦å“应的¾l“果了ã€?/span> 本æ¥è¯´åˆ°˜q™æƒ³å¤§æ¦‚有个收尾åQŒä½†æ˜¯æ€»è§‰å¾—还没有把一些问题说é€å½»ã€‚çƒ¦æ€§æƒ³å†æ·±å…¥å†™å†™ã€?br />
从套接å—è¡ç”Ÿåˆ°RMIä»£ç æ€èµ\
]]>
对于HashMap主è¦ä»¥é”®å€?/span>(key-value)çš„æ–¹å¼æ¥ä½“现åQŒç¬¼¾lŸçš„说就是采ç”?/span>key值的哈希½Ž—法æ¥ï¼Œå¤–åŠ å–余最¾lˆèŽ·å–烦引,而这个烦引å¯ä»¥è®¤å®šæ˜¯ä¸€¿U地å€åQŒæ—¢è€ŒæŠŠç›¸åº”çš?/span>valueå˜å‚¨åœ¨åœ°å€æŒ‡å‘内容ä¸ã€‚è¿™æ ¯‚¯´æˆ–许比较概念化,也å¯èƒ½å¤˜qîC¸å¤Ÿæ¸…楚,æ¥çœ‹åˆ—弿›´åŠ æ¸…æ™°åQ?/span>
int hash=key.hashCode();//------------------------1
int index=hash%table.lenth;//table表示当å‰å¯¹è±¡çš„é•¿åº?/span>-----------------------2
其实最¾lˆå°±æ˜¯è¿™ä¸¤ä¸ªå¼å军_®šäº†å€¼å¾—å˜å‚¨ä½ç½®ã€‚但是以上两个表辑ּ˜q˜æœ‰‹Æ ç¼ºã€‚äØ“ä»€ä¹ˆè¿™ä¹ˆè¯´åQŸä¾‹å¦‚在key.hashCode()åŽå¯èƒ½å˜åœ¨æ˜¯ä¸€ä¸ªè´Ÿæ•´æ•°åQŒä½ 会问åQšæ˜¯å•Šï¼Œé‚£è¿™ä¸ªæ—¶å€™æ€Žä¹ˆåŠžå‘¢åQŸæ‰€ä»¥åœ¨˜q™é‡Œž®±éœ€è¦è¿›ä¸€æ¥åŠ å¼ºæ”¹é€ å¼å?/span>2了,修改åŽçš„åQ?/span>
int index=åQ?/span>hash&Ox7FFFFFFF)%table.lenth;
到这里刘qähƒ‘了,ä¸ÞZ»€ä¹ˆä¸Šé¢æ˜¯˜q™æ ·çš„å‘¢åQŸå¯¹äºŽå…ˆå‰æˆ‘们谈到在hash有å¯èƒ½äñ”生负数的情况åQŒè¿™é‡Œæˆ‘们ä‹É用当å‰çš„hashåšä¸€ä¸?#8220;ä¸?#8221;æ“作åQŒåœ¨˜q™é‡Œéœ€è¦å’Œint最大的值相“ä¸?#8221;。这æ ïLš„è¯å°±å¯ä»¥ä¿è¯æ•°æ®çš„统一性,把有½W¦å·çš„æ•°å€¼ç»™“ä¸?#8221;æŽ‰ã€‚è€Œä¸€èˆ¬è¿™é‡Œæˆ‘ä»¬æŠŠäºŒè¿›åˆ¶çš„æ•°å€ÆD{æ¢æˆ16˜q›åˆ¶çš„å°±å˜æˆäº†ï¼šOx7FFFFFFF。(注:与æ“作的方å¼ä¸ºï¼Œä¸åŒä¸?/span>0åQŒç›¸åŒäØ“1åQ‰ã€‚而对äº?/span>hashCode()的方法一般有åQ?/span>
public int hashCode(){
int hash=0,offset,len=count;
char[] var=value;
for(int i=0;i<len;i++){
h=31*hash+var[offset++];
}
return hash;
}
说铘q™é‡Œå¤§å®¶å¯èƒ½ä¼šè¯´åQŒåˆ°˜q™é‡Œ½Ž—完事了å§ã€‚ä½†æ˜¯ä½ å¯æ›¾æƒ›_ˆ°å¦‚果数æ®éƒ½é‡‡ç”¨ä¸Šé¢çš„æ–¹å¼åQŒæœ€¾lˆå¾—到的å¯èƒ½indexä¼šç›¸åŒæ€Žä¹ˆåŠžå‘¢åQŸå¦‚æžœä½ æƒ›_ˆ°çš„è¯åQŒé‚£æå–œä½?/span>!åˆå¢ž˜q›ä¸€æ¥äº†åQŒè¿™é‡Œå°±æ˜¯è¦è¯´åˆ°ä¸€ä¸ªåè¯ï¼šå†²çªçŽ‡ã€‚æ˜¯çš„å°±æ˜¯å‰é¢è¯´é“的一æ—?/span>indexæœ‰ç›¸åŒæ€Žä¹ˆåŠžï¼Ÿæ•°æ®åˆè¯¥å¦‚ä½•å˜æ”¾å‘¢ï¼Œè€Œä¸”˜q™ä¸ªåœ¨æ•°æ®é‡éžå¸¸åºžå¤§çš„æ—¶å€™è¿™ä¸ªåŸºçŽ‡æ›´å¤§ã€‚è¿™é‡ŒæŒ‰ç…§ç®—æ³•éœ€è¦æ˜Ž¼‹®çš„一点:æ¯ä¸ªé”®ï¼ˆkeyåQ‰è¢«æ•£åˆ—分布åˆîC“Q何一个数¾l„烦引的å¯èƒ½æ€§ç›¸åŒï¼Œè€Œä¸”ä¸å–决于其它键分布的ä½ç½®ã€‚è¿™å¥è¯æ€Žä¹ˆç†è§£å‘¢ï¼Ÿä»Žæ¦‚率论的角度,也就是说如果key的个数达åˆîC¸€ä¸ªæžé™ï¼Œæ¯ä¸ªkey分布的机率都是函{‰çš„。更˜q›ä¸€æ¥å°±æ˜¯ï¼šå³ä¾¿key1ä¸ç‰äº?/span>key2也还是å¯èƒ?/span>key1.hashCode()=key2.hashCode()ã€?/span>
对于早期的解军_†²½Hçš„æ–ÒŽ³•æœ‰æŠ˜å æ³•åQ?/span>folding)åQŒä¾‹å¦‚我们在åšç³»¾lŸçš„æ—¶å€™æœ‰æ—¶å€™ä¼šé‡‡ç”¨éƒ¨é—¨¾~–å·é™„åŠ åˆ°æŸä¸ªå•æ®æ ‡å·åŽåQŒè¿™é‡Œæ¯”如äñ”生一ä¸?/span>9ï½?/span>11ä½çš„¾~–ç ã€‚é€šè¿‡å¯¹åŠæŠ˜å åšã€?/span>
现在的ç–略有åQ?/span>
1. 键弿•£åˆ—
2. 开攑֜°å€æ³?/span>
在了解这两个½{–ç•¥å‰ï¼Œæˆ‘ä»¬å…ˆå®šä¹‰æ¸…æ¥šå‡ ä¸ªåè¯è§£é‡Šï¼š
threshold[阀å€?/span>]åQŒå¯¹è±¡å¤§ž®çš„边界å€?/span>;
loadFactor[åŠ è²å› å]=n/m åQ›å…¶ä¸?/span>nä»£è¡¨å¯¹è±¡å…ƒç´ ä¸ªæ•°åQ?/span>m表示当å‰è¡¨çš„容积最大å€?/span>
threshold=(int)table.length*loadFactor
æ¸…æ™°äº†è¿™å‡ ä¸ªå®šä¹‰åQŒæˆ‘们冿¥çœ‹å…·ä½“的解å†Ïx–¹å¼?/span>
键弿•£åˆ—åQ?/span>
我们直接看一个实例,˜q™æ ·ž®±æ›´åŠ æ¸…æ™°å®ƒçš„å·¥ä½œæ–¹å¼ï¼Œä»Žè€Œé¿å…æ–‡å—定义。我们这里还是æ¥ä¸¾ä¸€ä¸ªå›¾ä¹¦ç¼–åïLš„例ååQŒä¸‹é¢æ¯”如有˜q™æ ·ä¸€äº›ç¼–åøP¼š
78938-0000
45678-0001
72678-0002
24678-0001
16678-0001
98678-0003
85678-0002
45232-0004
æ¥éª¤åQ?/span>
1. 把编å·ä½œä¸?/span>key,å»I¼šint hash=key.hashCode();
2. int index=hash%表大ž®ï¼›
3. 逿¥æŒ‰é¡ºåºæ’入对象ä¸
现在问题出现了:对于¾~–å·é€šè¿‡æ•£åˆ—½Ž—法åŽå¾ˆå¯èƒ½äº§ç”Ÿç›¸åŒçš„烦引å€û|¼Œæ„味ç€å˜åœ¨å†²çªã€?/span>
解释上é¢çš„æ“ä½œï¼šå¦‚æžœå¯¹äºŽkey.hashCode()产生了冲½H(比如途ä¸å¯¹äºŽæ’å…¥24678-0001对于通过哈希½Ž—法åŽå¯èƒ½äñ”生的index或许也是501åQ‰ï¼Œæ—¢è€ŒæŠŠç›¸åº”çš„å‰é©±æœ‰ç›¸åŒçš?/span>index的对象指å‘当å‰å¼•用。这也就是大家认定的å•链表方å¼ã€‚以æ¤ç±»æŽ?/span>…
而这里å˜åœ¨å†²½Hå¯¹è±¡çš„å…ƒç´ æ”‘Öœ¨Entry对象ä¸ï¼ŒEntryå…ähœ‰ä»¥ä¸‹ä¸€äº›å±žæ€§ï¼š
int hash;
Object key;
Entry next;
对于Entry对象ž®±å¯ä»¥ç›´æŽ¥è¿½æº¯åˆ°é“¾è¡¨æ•°æ®¾l“æž„ä½“ä¸æŸ¥é˜…ã€?/span>
开攑֜°å€æ³•:
1. ¾U¿æ€§åœ°å€æŽ¢æµ‹æ³•:
如何ç†è§£˜q™ä¸ªæ¦‚念呢,一å¥è¯åQšå°±æ˜¯é€šè¿‡½Ž—法规则在对象地å€N+1䏿Ÿ¥é˜…找åˆîCØ“NULL的烦引内å®V€?/span>
å¤„ç†æ–¹å¼åQšå¦‚æž?/span>index索引与当å‰çš„index有冲½H,åÏxŠŠå½“å‰çš„烦å¼?/span>index+1。如果在index+1å·²ç»å˜åœ¨å ä½çŽ°è±¡åQ?/span>index+1的内容ä¸ä¸?/span>NULLåQ‰è¯•图接ç€index+2æ‰§è¡Œã€‚ã€‚ã€‚ç›´åˆ°æ‰¾åˆ°çƒ¦å¼•äØ“å†…å®¹ä¸?/span>NULLçš„äØ“æ¢ã€‚è¿™¿Uå¤„ç†æ–¹å¼ä¹Ÿå«ï¼š¾U¿æ€§åœ°å€æŽ¢æµ‹æ³?/span>(offset-of-1)
如果采用¾U¿æ€§åœ°å€æŽ¢æµ‹æ³•会带æ¥ä¸€ä¸ªæ•ˆçŽ‡çš„ä¸è‰¯å½±å“。现在我们æ¥åˆ†æž˜q™ç§æ–¹å¼ä¼šå¸¦æ¥å“ªäº›ä¸è‰¯å› ç´ ã€‚å¤§å®¶è¯•æƒ³ä¸‹å¦‚æžœä¸€ä¸ªéžå¸¸åºžå¤§çš„æ•°æ®å˜å‚¨åœ?/span>Mapä¸ï¼Œå‡å¦‚在æŸäº›è®°å½•集䏿œ‰ä¸€äº›æ•°æ®éžå¸¸ç›¸ä¼û|¼ˆä»–们产生的烦引在内å˜çš„æŸä¸ªå—ä¸éžå¸¸çš„密集åQ‰ï¼Œä¹Ÿå°±æ˜¯è¯´ä»–ä»¬äº§ç”Ÿçš„çƒ¦å¼•åœ°å€æ˜¯ä¸€ä¸ªè¿ž¾læ•°å€û|¼Œè€Œé€ æˆæ•°æ®æˆå—现象。å¦ä¸€ä¸ªè‡´å‘½çš„问题ž®±æ˜¯åœ¨æ•°æ®åˆ 除åŽåQŒå¦‚果冋ơ查询å¯èƒ½æ— 法定åˆîC¸‹ä¸€ä¸ªè¿ž¾læ•°å—,˜q™ä¸ªåˆæ˜¯ä¸€ä¸ªä»€ä¹ˆæ¦‚念呢åQŸä¾‹å¦‚以下图片就很好的说明开å‘åœ°å€æ•£åˆ—å¦‚ä½•æŠŠæ•°æ®æŒ‰ç…§ç®—法æ’入到对象ä¸ï¼š
对于上图的注释æ¥éª¤è¯´æ˜Žï¼š
从数æ?#8220;78938-0000”开始通过哈希½Ž—法按顺åºä¾‹Æ¡æ’入到对象ä¸ï¼Œä¾‹å¦‚78938-0000通过æ?/span>
½Ž—å¾—åˆ°çƒ¦å¼•äØ“0åQŒå½“剿‰€æŒ‡å†…容䨓NULL所以直接æ’入;45678-0001åŒæ ·é€šè¿‡æ¢ç®—得到索引为地å€501所指内容,当å‰å†…容ä¸?/span>NULL所以也å¯ä»¥æ’å…¥åQ?/span>72678-0002得到索引502所指内容,当å‰å†…容ä¸?/span>NULL也å¯ä»¥æ’入;è¯äh³¨æ„当24678-0001å¾—åˆ°ç´¢å¼•ä¹ŸäØ“501åQŒå½“å‰åœ°å€æ‰€æŒ‡å†…容䨓45678-0001。å³è¡¨ç¤ºå½“剿•°æ®å˜åœ¨å†²çªåQŒåˆ™ç›´æŽ¥å¯¹åœ°å€501+1=502所指å‘内容ä¸?/span>72678-0002ä¸äØ“NULL也ä¸å…许æ’å…¥åQŒå†‹Æ¡å¯¹ç´¢å¼•502+1=503æ‰€æŒ‡å†…å®¹äØ“NULLå…许æ’入。。。例ơ类推åªè¦å¯¹äºŽçƒ¦å¼•å˜åœ¨å†²½HçŽ°è±¡ï¼Œåˆ™é€æ¬¡ä¸‹ç§»ä½çŸ¥é“çƒ¦å¼•åœ°å€æ‰€æŒ‡äØ“NULLåQ›å¦‚果烦引ä¸å†²çªåˆ™è¿˜æ˜¯æŒ‰ç…§ç®—法放入内å®V€‚对于这æ ïLš„对象是一¿Uæ’入方å¼ï¼ŒæŽ¥ä¸‹æ¥å°±æ˜¯æˆ‘ä»¬çš„åˆ é™¤(remove)æ–ÒŽ³•了。按照常ç†å¯¹äºŽåˆ 除,方å¼åŸºæœ¬åŒºåˆ«ä¸å¤§ã€‚但是现在问题åˆå‡ºçŽ°äº†ï¼Œå¦‚æžœåˆ é™¤çš„æŸä¸ªæ•°æ®æ˜¯ä¸€ä¸ªå˜åœ¨å†²½H烦引的内容åQŒå¸¦æ¥å޾l的问题åˆä¼šæŽ¥è¸µè€Œæ¥ã€‚那是什么问题呢åQŸæˆ‘ä»¬è¿˜æ˜¯åŒæ äh¥çœ‹çœ‹å›„¡¤ºçš„æ˜qŽÍ¼Œå¯¹äºŽå›?/span>-2ä¸å¦‚æžœåˆ é™?/span>(remove)æ•°æ®24678-0001的方法如下图所½Cºï¼š
对于我们会想当然的觉得åªè¦æŠŠæŒ‡å‘数殾|®äØ“NULLž®±å¯ä»?/span>,˜q™æ ·çš„åšæ³•å¯¹äºŽåˆ é™¤æ¥è¯´å½“ç„¶æ˜¯æ²¡æœ‰é—®é¢˜çš„ã€‚å¦‚æžœå†‹Æ¡å®šä½æ£€ç´¢æ•°æ?/span>16678-0001ä¸ä¼šæˆåŠŸåQŒå› 䏸™¿™ä¸ªæ—¶å€™ä»¥å‰çš„链èµ\å·²ç»å µä¸Šäº†ï¼Œä½†æ˜¯éœ€è¦æ£€ç´¢çš„æ•°æ®äº‹å®žä¸Šåˆå˜åœ¨ã€‚那我们如何æ¥è§£å†Œ™¿™ä¸ªé—®é¢˜å‘¢åQŸå¯¹äº?/span>JDKä¸çš„Entry¾cÖM¸çš„æ–¹æ³•å˜åœ¨ä¸€ä¸ªï¼šboolean markedForRemoval;å®ƒå°±æ˜¯ä¸€ä¸ªå…¸åž‹çš„åˆ é™¤æ ‡å¿—ä½ï¼Œå¯¹äºŽå¯¹è±¡ä¸å¦‚果需è¦åˆ 除时åQŒæˆ‘ä»¬åªæ˜¯å¯¹äºŽå®ƒåšä¸€ä¸?#8220;è½¯åˆ é™?#8221;å³ç½®ä¸€ä¸ªæ ‡å¿—ä½ä¸?/span>truež®±å¯ä»¥ã€‚而æ’入时åQŒé»˜è®¤çжæ€äØ“falsež®±å¯ä»¥ã€‚è¿™æ ïLš„è¯å°±å˜æˆä»¥ä¸‹å›¾æ‰€½Cºï¼š
é€šè¿‡ä»¥ä¸Šæ–¹å¼æ›´å¥½çš„解军_†²½H地å€åˆ é™¤æ•°æ®æ— 法‹‚€ç´¢å…¶ä»–链路数æ®é—®é¢˜äº†ã€?/span>
2. åŒæ•£åˆ—(余商法)
在了解开攑֜°å€æ•£åˆ—的时候我们一直在说解å†Ïx–¹æ³•,但是大家都知é“一个数æ®ç»“构的完善更多的是需è¦é«˜æ•ˆçš„½Ž—æ³•ã€‚è¿™å½“ä¸æˆ‘们崿²¡æœ‰æ¶‰åŠåˆ°ã€‚æŽ¥ä¸‹æ¥æˆ‘们ž®±æ¥çœ‹çœ‹åœ¨å¼€æ”‘Öœ°å€æ•£åˆ—ä¸å®ƒå˜åœ¨çš„一些丑³ä»¥åŠå¦‚何改善这æ ïLš„æ–ÒŽ³•åQŒæ—¢è€Œè¾¾åˆ°æ— 论是在方法的解决上还是在½Ž—æ³•çš„å¤æ‚åº¦ä¸Šæ›´åŠ è¾¾åˆ°é«˜æ•ˆçš„æ–ÒŽ¡ˆã€?/span>
在图2-1ä¸ç±»ä¼ÆD¿™æ ·ä¸€äº›æ•°æ®æ’入进对象åQŒå˜åœ¨å†²½Hé‡‡ç”¨ä¸æ–ç§»ä½åŠ ä¸€çš„æ–¹å¼ï¼Œç›´åˆ°æ‰‘Öˆ°ä¸äØ“NULL内容的烦引地å€ã€‚ä¹Ÿæ£æ˜¯ç”׃ºŽ˜q™æ ·ä¸€¿Uå¯èƒ½åŠ å¤§äº†æ—‰™—´ä¸Šçš„å˜æ…¢ã€‚å¤§å®¶æ˜¯å¦æ³¨æ„到åƒå›¾˜q™æ ·ä¸€äº›æ•°æ®ç›®å‰å‘ˆçŽ°å‡ºä¸€¿U连¾l烦引的æ’å…¥åQŒè€Œä¸”是一¿Uæˆå—是的数æ®ã€‚如果数æ®é‡éžå¸¸çš„庞大,或许˜q™ç§å¯èƒ½æ€§æ›´å¤§ã€‚å°½½Ž¡å®ƒè§£å†³äº†å†²½H,但是对于数残‚€ç´¢çš„æ—‰™—´åº¦æ¥è¯ß_¼Œæˆ‘ä»¬æ˜¯ä¸æ•¢æƒ³è±¡çš„。所有分布到åŒä¸€ä¸ªçƒ¦å¼?/span>index上的keyä¿æŒç›¸åŒçš„èµ\径:index,index+1,index+2…便¤¾cÀLŽ¨ã€‚æ›´åŠ ç³Ÿ¾p•的是烦引键值的‹‚€ç´¢éœ€è¦ä»Žç´¢å¼•å¼€å§‹æŸ¥æ‰¾ã€‚æ£æ˜¯è¿™æ ïLš„åŽŸå› åQŒå¯¹äºŽçº¿æ€§æŽ¢ç´¢æ³•æˆ‘ä»¬éœ€è¦æ›´˜q›ä¸€æ¥çš„æ”¹è¿›ã€‚è€Œåˆšæ‰æ‰€æè¿°˜q™ç§æˆå—出现的数æ®ä¹Ÿž®±å®šä¹‰æˆåQšç°‡ã€‚è€Œè¿™æ ·ä¸€¿UçŽ°è±¡ç§°ä¹‹äØ“åQšä¸»½‡çŽ°è±¡ã€?/span>
åQˆä¸»½‡ï¼šž®±æ˜¯å†²çªå¤„ç†å…许½‡åŠ é€Ÿå¢žé•¿æ—¶å‡ºçŽ°çš„çŽ°è±¡ï¼‰è€Œå¼€æ”‘Ö¼åœ°å€å†²çªä¹Ÿæ˜¯å…许ä¸È°‡çŽ°è±¡äº§ç”Ÿçš„ã€‚é‚£æˆ‘ä»¬å¦‚ä½•æ¥é¿å…è¿™¿U主½‡çŽ°è±¡å‘¢åQŸè¿™ä¸ªæ–¹å¼å°±æ˜¯æˆ‘ä»¬è¦æ¥è¯´æ˜Žçš„åQšåŒæ•£åˆ—è§£å†³å†²çªæ³•了。主è¦çš„æ–¹å¼ä¸ºï¼š
u int hash=key.hasCode();
u int index=(hash&Ox7FFFFFFF)%table.length;
u 按照以上方å¼å¾—到索引å˜åœ¨å†²çªåQŒåˆ™å¼€å§‹å¯¹å½“å‰ç´¢å¼•¿UÖM½åQŒè€Œç§»ä½æ–¹å¼äØ“åQ?/span>
offset=(hash&Ox7FFFFFFF)/table.length;
u 如果½W¬ä¸€‹Æ¡ç§»ä½è¿˜å˜åœ¨åŒæ ·çš„冲½H,则ç‘ô¾l:当å‰å†²çªç´¢å¼•ä½ç½®åQˆçƒ¦å¼•å·+余数åQ?/span>%è¡?/span>.length
u 如果å˜åœ¨çš„余数æ°å¥½æ˜¯è¡¨çš„倿•°åQŒåˆ™ä½œå¿UÖM½¾|®äؓ一下移åQŒä¾æ¤ç±»æŽ?/span>
˜q™æ ·åŒæ•£åˆ—冲½H处ç†å°±é¿å…了主½‡çŽ°è±¡ã€‚è‡³äº?/span>HashSet的原ç†åŸºæœ¬å’Œå®ƒæ˜¯ä¸€è‡´çš„åQŒè¿™é‡Œä¸å†å¤˜q°ã€‚在˜q™é‡Œå…¶å®ž˜q˜æ˜¯ä¸»è¦è¯´äº†ä¸€äº›ç®€å•的解决方å¼åQŒè€Œä¸”éƒ½æ˜¯åœ¨ä¸€äº›å…·ä½“å‚æ•°æ»¡‘Ïx¡ä»¶ä¸‹çš„说明,åƒä¸€æ—¦æ•°æ®è¶…˜q‡åˆå§‹å€ÆD¯¥éœ€è¦?/span>rehashåQŒåŠ è½½å› å一旦大äº?/span>1.0是何¿U情å†ëЉ½{‰ã€‚还有很多问题都å¯ä»¥å€¼å¾—æˆ‘ä»¬æ›´åŠ ˜q›ä¸€æ¥è®¨è®ºçš„åQŒæ¯”如:åœ?/span>java.util.HashMapä¸çš„åŠ è²å› åä¸ÞZ»€ä¹ˆä¼šæ˜?/span>0.75åQŒè€Œå®ƒé»˜è®¤çš„åˆå§‹å¤§ž®äØ“ä»€ä¹ˆåˆæ˜?/span>16½{‰ç‰˜q™äº›é—®é¢˜éƒ½è¿˜å€¼å¾—说明。è¦è¯´æ˜Ž˜q™äº›é—®é¢˜å¯èƒ½åˆéœ€è¦æ›´åŠ è¯¦ž®½çš„说明清楚ã€?/span>