ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品久久久久久久久,精品久久久久一区二区国产,色婷婷综合久久久久久http://www.aygfsteel.com/nod0620/zh-cnMon, 28 Jul 2025 11:30:59 GMTMon, 28 Jul 2025 11:30:59 GMT60java io以及(qi¨¢ng)unix io模型http://www.aygfsteel.com/nod0620/articles/359297.htmlnod0620nod0620Thu, 29 Sep 2011 05:15:00 GMThttp://www.aygfsteel.com/nod0620/articles/359297.htmlhttp://www.aygfsteel.com/nod0620/comments/359297.htmlhttp://www.aygfsteel.com/nod0620/articles/359297.html#Feedback2http://www.aygfsteel.com/nod0620/comments/commentRss/359297.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/359297.html阅读全文

]]>
java ¾U¿ç¨‹æ±?/title><link>http://www.aygfsteel.com/nod0620/articles/359095.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Tue, 20 Sep 2011 14:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/nod0620/articles/359095.html</guid><wfw:comment>http://www.aygfsteel.com/nod0620/comments/359095.html</wfw:comment><comments>http://www.aygfsteel.com/nod0620/articles/359095.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/nod0620/comments/commentRss/359095.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/nod0620/services/trackbacks/359095.html</trackback:ping><description><![CDATA[     摘要: 囑ַ¦è¾ÒŽ(gu¨©)˜¯¾U¿ç¨‹æ± çš„¾cȝ»“构,双™¾¹æ˜¯æ”¾å…¥çº¿½E‹æ± æ‰§è¡Œçš„ä“Q务类¾l“æž„ExecutorServiceExecutorService定义了线½E‹æ± çš„基本的æ–ÒŽ(gu¨©)³•åQŒAbstractExecutorService是个抽象¾c»ï¼Œå®žçŽ°äº†ExecutorService的部分,主要是实çŽîCº†å‡ ä¸ªsubmit()æ–ÒŽ(gu¨©)³•åQŒåƈ且提供方法将提交˜q›æ¥çš„ä“Q务封装成FutureTask,ThreadPoolExecutor则实现线½E‹æ± çš„管理Futu...  <a href='http://www.aygfsteel.com/nod0620/articles/359095.html'>阅读全文</a><img src ="http://www.aygfsteel.com/nod0620/aggbug/359095.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/nod0620/" target="_blank">nod0620</a> 2011-09-20 22:27 <a href="http://www.aygfsteel.com/nod0620/articles/359095.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java thread 之Lockhttp://www.aygfsteel.com/nod0620/articles/358835.htmlnod0620nod0620Sat, 17 Sep 2011 16:12:00 GMThttp://www.aygfsteel.com/nod0620/articles/358835.htmlhttp://www.aygfsteel.com/nod0620/comments/358835.htmlhttp://www.aygfsteel.com/nod0620/articles/358835.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/358835.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/358835.htmlconcurrent包里面有很多Lock的具体实玎ͼŒå…¶å…·ä½“的实现都是åŸÞZºŽAQS实现çš?br />
ReentrantLock
ReentrantLock是可重入的互斥锁åQŒé‡ç‚ÒŽ(gu¨©)˜¯é‡å…¥å’Œäº’斥,ReentrantLock ž®†ç”±æœ€˜q‘成功获得锁的线½E‹æ‰€æŒæœ‰åQŒå½“˜q™ä¸ª¾U¿ç¨‹å†æ¬¡ž®è¯•拥有˜q™ä¸ªLock时就是重入。互斥就æ˜?br />在某一旉™—´åªæœ‰ä¸€ä¸ªçº¿½E‹èƒ½æŒæœ‰Lockã€?br />    public void lock() {
        sync.lock();
    }
获得锁方法,Sync是AQS的抽象子¾c»ï¼Œå®žçŽ°å¯é‡å…¥å’Œäº’æ–¥çš„å¤§éƒ¨åˆ†åŠŸèƒ½ã€‚åœ¨Sync的子¾cÖM¸­æœ‰FairSyncå’ŒNonfairSync两种代表公åã^锁策略和非公òq³é”½{–ç•¥

Sync lockæ–ÒŽ(gu¨©)³•留给子类åŽÕd®žçŽŽÍ¼ŒNonfairSync的实玎ͼš(x¨¬)
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
不管是不是有其他¾U¿ç¨‹åœ¨AQS的阻塞的队列里面åQŒå¦‚果当前线½E‹èƒ½èŽ·å¾—¾U¿ç¨‹åQŒå°±ç›´æŽ¥èŽ·å¾—¾U¿ç¨‹åQŒä¸è¡Œçš„话执行AQSçš„acquire()æ–ÒŽ(gu¨©)³•åQŒåŸºæœ¬å°±æ˜¯è¿›å…¥é˜»å¡žé˜Ÿåˆ—的命了ã€?br />关键ç‚?AQSçš„acquire()中调用的tryAcquire(int arg)是留¾l™å­¾cÕd®žçŽ°çš„åQŒæ˜¯åœ¨è¿›å…¥é˜»å¡žé˜Ÿåˆ—前再尝试一‹Æ¡èŽ·å–é”(lock()æ–ÒŽ(gu¨©)³•到这个点上面可能其他¾U¿ç¨‹å·²ç»é‡Šæ”¾é”?

NonfairSync的tryAcquire(int arg)调用的nonfairTryAcquire()实现:
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {//关键ç‚?
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;//关键ç‚?
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
关键ç‚?åQšstateä¸?åQŒæ²¡æœ‰çº¿½E‹è¯·æ±‚锁åQŒç›´æŽ¥åˆ†é…ç»™æœ¬çº¿½E?br />关键ç‚?.  如果本线½E‹å·²¾lå¾—到锁åQŒstateåŠ?åQŒå³é‡å…¥ã€?br />
FairSync的实�
    final void lock() {
            acquire(1);//关键ç‚?
        }
    protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (isFirst(current) && //关键ç‚?
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
关键ç‚?åQšå…¬òq³ç­–略,没有¾l™å½“前线½E‹ä¼˜æƒ?br />关键ç‚?åQšåˆ¤æ–­å½“前线½E‹æœ‰æ²¡æœ‰åœ¨é˜»å¡žé˜Ÿåˆ—çš„½W¬ä¸€ä½ï¼Œæ²¡åœ¨½W¬ä¸€ä½ä¸å¾€ä¸‹ç‘ô¾l­æ‰§è¡Œï¼Œ˜q™æ ·å…ˆç»™é˜Õd¡žé˜Ÿåˆ—的线½E‹æœºä¼?x¨¬),˜q™æ ·åšé€Ÿåº¦æ¯”较慢,吞吐量比较小

    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
 tryLockž®è¯•获得锁,不能获得话就直接˜q”回åQŒæ²¡æœ‰å…¬òq³ç­–略一说ã€?br />
unlock
    public void unlock() {
        sync.release(1);
    }
 
    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
tryRelease()留给AQS子类执行åQ?br />        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
如果stateè¢«å‡åŽè¿˜ä¸äØ“(f¨´)0åQŒè¡¨½Cø™¿™ä¸ªé”è¢«ä¸€ä¸ªçº¿½E‹é‡å…¥åŽ˜q˜æ²¡æœ‰å®Œå…¨é‡Šæ”¾ï¼Œrelease()æ–ÒŽ(gu¨©)³•后面不会(x¨¬)执行åQŒä¹Ÿž®±æ˜¯ä¸ä¼š(x¨¬)执行unparké˜Õd¡žé˜Ÿåˆ—中的¾U¿ç¨‹.


ReentrantReadWriteLock
ReentrantReadWriteLock内部有两个锁åQšäº’斥可重入的WriteLock和共享的ReadLock
内部实现中state字段的高16位代表的是read countåQŒä½Ž16位代表的是write count
AQS的实çŽîC¹Ÿæœ‰NonfairSyncå’ŒFairSync之分åQ?br />主要区别是同时有è¯Õd†™¾U¿ç¨‹æ—¶å€™å¯¹å¾…读写线½E‹ç­–略不同ã€?br />NonfairSync:
final boolean writerShouldBlock(Thread current) {
            return false; // writers can always barge
        }
        final boolean readerShouldBlock(Thread current) {
            /* As a heuristic to avoid indefinite writer starvation,
             * block if the thread that momentarily appears to be head
             * of queue, if one exists, is a waiting writer. This is
             * only a probablistic effect since a new reader will not
             * block if there is a waiting writer behind other enabled
             * readers that have not yet drained from the queue.
             */
            return apparentlyFirstQueuedIsExclusive();
        }
write永远都不é˜Õd¡žåQŒread的话看阻塞队列header之后的node是不是write的,如果是就é˜Õd¡žåQŒå¯ä»¥é¿å…read一直运行导致的write饥饿ã€?br />FairSyncåQ?br />      final boolean writerShouldBlock(Thread current) {
            // only proceed if queue is empty or current thread at head
            return !isFirst(current);
        }
        final boolean readerShouldBlock(Thread current) {
            // only proceed if queue is empty or current thread at head
            return !isFirst(current);
        }
writeå’Œread都有判断是不是阻塞队列header后的½W¬ä¸€ä¸ªnodeã€?br />
对于ReadLock
     public void lock() {
            sync.acquireShared(1);
        }
调用AQSçš„acquireShared()åQŒå…¶ä¸­ä¼š(x¨¬)执行留给AQS子类实现的tryAcquireShared():
 protected final int tryAcquireShared(int unused) {
            /*
             * Walkthrough:
             * 1. If write lock held by another thread, fail
             * 2. If count saturated, throw error
             * 3. Otherwise, this thread is eligible for
             *    lock wrt state, so ask if it should block
             *    because of queue policy. If not, try
             *    to grant by CASing state and updating count.
             *    Note that step does not check for reentrant
             *    acquires, which is postponed to full version
             *    to avoid having to check hold count in
             *    the more typical non-reentrant case.
             * 4. If step 3 fails either because thread
             *    apparently not eligible or CAS fails,
             *    chain to version with full retry loop.
             */
            Thread current = Thread.currentThread();
            int c = getState();
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current)
                return -1;
            if (sharedCount(c) == MAX_COUNT)
                throw new Error("Maximum lock count exceeded");
            if (!readerShouldBlock(current) &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                HoldCounter rh = cachedHoldCounter;
                if (rh == null || rh.tid != current.getId())
                    cachedHoldCounter = rh = readHolds.get();
                rh.count++;
                return 1;
            }
            return fullTryAcquireShared(current);
        }
½{–略是以下的几点åQ?br />1.如果当前write持有锁,直接˜q”回-1.
2.没有write持有锁,判断是否需要阻塞读è¯äh±‚åQŒä¹‹åŽåŽŸå­æ›´æ–°read count
3.上面成功后就˜q”回1åQŒä¸æˆåŠŸçš„è¯åœ¨åó@环中试着è¯Õd–åQ?br />     final int fullTryAcquireShared(Thread current) {
            /*
             * This code is in part redundant with that in
             * tryAcquireShared but is simpler overall by not
             * complicating tryAcquireShared with interactions between
             * retries and lazily reading hold counts.
             */
            HoldCounter rh = cachedHoldCounter;
            if (rh == null || rh.tid != current.getId())
                rh = readHolds.get();
            for (;;) {
                int c = getState();
                int w = exclusiveCount(c);
                if ((w != 0 && getExclusiveOwnerThread() != current) ||
                    ((rh.count | w) == 0 && readerShouldBlock(current)))
                    return -1;
                if (sharedCount(c) == MAX_COUNT)
                    throw new Error("Maximum lock count exceeded");
                if (compareAndSetState(c, c + SHARED_UNIT)) {
                    cachedHoldCounter = rh; // cache for release
                    rh.count++;
                    return 1;
                }
            }
        }
unLockæ–ÒŽ(gu¨©)³•ž®±æ˜¯ž®†read count å‡?åQŒç„¶åŽæŸ¥çœ‹é˜»å¡žé˜Ÿåˆ—有没有¾U¿ç¨‹éœ€è¦unpark

WriteLock的实现和ReetrantLock的实现是一致的
Semaphore
Semaphore是信号量的概念,主要控制同一旉™—´å†…对讉K—®èµ„源的线½E‹æ•°çš„æŽ§åˆ¶ã€‚底层实现是AQSçš?br />acquireShared()å’ŒreleaseShared().

CountDownLatch
CountDownLatch在完成一¾l„正在其他线½E‹ä¸­æ‰§è¡Œçš„æ“ä½œä¹‹å‰ï¼Œå…è®¸¾U¿ç¨‹½{‰å¾…直到他们完成操作
await()æ–ÒŽ(gu¨©)³•一直等到state=0åQŒåˆå§‹æ—¶CountDownLatch初始化stateä¸ÞZ¼ å…¥çš„æ•°å€û|¼Œä¸€ä¸ªçº¿½E?br />执行操作完成的话执行countDown()æ–ÒŽ(gu¨©)³•ž®†stateå‡?åQŒç›´åˆîCØ“(f¨´)0åQŒawait()æ–ÒŽ(gu¨©)³•不再é˜Õd¡žã€?br />
CyclicBarrier
当一¾l„线½E‹è°ƒç”¨CyclicBarrier.await()æ–ÒŽ(gu¨©)³•åQŒå°±ä¼?x¨¬)阻塞在那里åQŒå½“最后一个线½E‹è¿›å…¥è°ƒç”¨æ­¤æ–ÒŽ(gu¨©)³•æ—Óž¼Œž®±æ‰§è¡?br />一个公å…Þqš„Runnable.原理是:(x¨¬)初始化时有count属性,当前面count-1个线½E‹åˆ°æ¥éƒ½condition.await()åQŒç¬¬countä¸?br />¾U¿ç¨‹æ¥å°±æ‰§è¡Œå…¬å…±RunnableåQŒç„¶åŽæ‰§è¡Œcondition.signAll()æ–ÒŽ(gu¨©)³•来ä‹É得其他线½E‹ä»Žé˜Õd¡žä¸­è§£è„±å‡ºæ?




]]>
java thread 之AQShttp://www.aygfsteel.com/nod0620/articles/358638.htmlnod0620nod0620Thu, 15 Sep 2011 14:57:00 GMThttp://www.aygfsteel.com/nod0620/articles/358638.htmlhttp://www.aygfsteel.com/nod0620/comments/358638.htmlhttp://www.aygfsteel.com/nod0620/articles/358638.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/358638.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/358638.html阅读全文

]]>
java threadhttp://www.aygfsteel.com/nod0620/articles/358439.htmlnod0620nod0620Wed, 14 Sep 2011 08:53:00 GMThttp://www.aygfsteel.com/nod0620/articles/358439.htmlhttp://www.aygfsteel.com/nod0620/comments/358439.htmlhttp://www.aygfsteel.com/nod0620/articles/358439.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/358439.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/358439.html¾U¿ç¨‹çжæ€?/strong>
   jdk中线½E‹çŠ¶æ€åˆ†ä¸?new,runnable,blocked,waiting,timed_waiting,dead.其中new为刚创徏˜q˜æ²¡æœ‰å¼€å§‹æ‰§è¡Œçš„状态,
而runnable状态分为可以执行和正在执行åQŒå¯ä»¥æ‰§è¡Œæ˜¯å› äØ“(f¨´)可能要等cpuæ—‰™—´ç‰‡ç­‰ã€‚blocked状态是指线½E‹åœ¨é˜Õd¡ž½{‰å¾…监视器的锁。waiting是指执行了Object.wait()åQŒThread.join()½{‰æ–¹æ³•进入waiting状态;timed_waiting是指带时间数的waiting状态,在时间到达之前都是在waiting状态,dead状态是指结束ä“Q务的¾U¿ç¨‹çŠ¶æ€ï¼Œå†ä¹Ÿä¸èƒ½å›žåˆ°runnable状态了ã€?br />
在线½E‹ä¸­æœ‰waiting setå’Œready set概念ã€?br />当一个对象执行Object.wait()/Object.join()åQŒè¯¥¾U¿ç¨‹˜q›å…¥waiting setåQŒåŒæ—‰™œ€è¦é‡Šæ”„¡›‘视器的锁。监视器也是一个普通对象,在加上一些关键语法后åQŒå°±èƒ½æˆä¸ºç›‘视器ã€?br />当一个对象执行Object.notify()æ—Óž¼Œæ˜¯åœ¨waiting set选择一个thread˜q›å…¥ready setåQŒå½“˜q™ä¸ªthread能获得这个监视器的锁时候,ž®±å¯ä»¥è¿›å…¥runnable状态,否则ž®±å¾…在ready setåQŒnotifyAll()是通知waiting set里面的所有线½E‹ï¼Œç„¶åŽé€‰æ‹©å…¶ä¸­çš„一个,不确定是哪一个,¾U¿ç¨‹çš„优先çñ”也只是一个提½Cºå’ŒæŒ‡å¯¼ã€?br />Object.wait(time)/Object.join(time)æ–ÒŽ(gu¨©)³•˜q™äº›éƒ½æ˜¯åœ¨æ—¶é—´é™åˆ¶åˆ°è¾¾ä¹‹å‰thread在waiting setåQŒæ—¶é—´åˆ°æœŸä¹‹åŽè‡ªåŠ¨è¿›å…¥ready setã€?br />Thread.sleep()/Thread.yield()执行时thread都不ä¼?x¨¬)放弃监视器的锁åQŒåªæ˜¯è¿›å…¥ready setåQŒThread.sleep()只是在指定的旉™—´å†…休眠,得不åˆîC“Q何的资源.Thread.yield()只是提示thread工作差不多完成了åQŒå¯ä»¥è®©æ­¥ç»™å…¶ä»–ThreadåQŒè¿™ä¸ªè®©æ­¥ä¸ä¿è¯å®ŒæˆåQŒè¿™ä¸ªä¹Ÿåªå¯¹åŒç­‰¾U§çš„¾U¿ç¨‹æœ‰æ•ˆã€?br />
监视�/strong>
   java使用监视器来表示同步锁,在Java里面åQŒä“Q何一个Object Reference都可以作为同步锁åQŒåªè¦ä‹É用synchronizedåQ?br />
public static final Object signal = new Object();
f1(){
   synchronized(signal){

   }
}
在jvm内部synchronizedä¼?x¨¬)被表示成monitorenterå’Œmonitorexit;在一个时间段åQŒåªæœ‰ä¸€ä¸ªçº¿½E‹èƒ½æŒæœ‰monitoråQŒä¹Ÿž®±æ˜¯åœ¨monitorenter里面åQŒä¹Ÿž®Þp¾¾åˆîCº†åŒæ­¥çš„ç›®çš?当想获得一个类变量锁的时候,可以使用˜q™ä¸ª¾cȝš„class¾c…R€?br />
内存模型
在jvm规范中规定java内存模型是java  thread  work  memoryå’Œjava main  memory两部åˆ?br />每个thread一个thread  memoryåQŒåˆå§‹äØ“(f¨´)½Iºï¼Œå¿…要时和main memory通信


规范规定了工作内存和ä¸Õd†…存之间通信çš?个行为:(x¨¬)use, assign, load, store,read,write, lock, and unlock
use:使用一个线½E‹å·¥ä½œå†…存中的变量,看成¾U¿ç¨‹çš„行ä¸?br />assign:讄¡½®ä¸€ä¸ªçº¿½E‹å·¥ä½œå†…存中的变量,讄¡½®çš„值来自线½E‹æ‰§è¡Œå¼•擎,看成¾U¿ç¨‹çš„行ä¸?br />readåQšæŠŠä¸Õd†…å­˜çš„å€ÆD¯»åˆ°çº¿½E‹å·¥ä½œå†…存当中,看成ä¸Õd†…å­˜çš„è¡ŒäØ“(f¨´)
loadåQšåœ¨read之后执行åQŒçœŸæ­£çš„æŠŠå€ÆD¯»åˆ°åˆ°å·¥ä½œå†…存当中åQŒçœ‹æˆçº¿½E‹çš„è¡ŒäØ“(f¨´)
storeåQšä¿å­˜å·¥ä½œå†…存的å€û|¼Œ½{‰ä¸‹åœ¨æ‰§è¡Œwrite后传输给ä¸Õd†…存,看成¾U¿ç¨‹çš„行ä¸?br />
writeåQšåœ¨store后执行,看成ä¸Õd†…å­˜çš„è¡ŒäØ“(f¨´)
lockå’Œunlockæ˜¯èŽ·å–ç›‘è§†å™¨é”å’Œé‡Šæ”¾é”çš„è¡ŒäØ“(f¨´)åQŒæ˜¯½W¬ä¸‰æ–¹synchronizedè¡ŒäØ“(f¨´)


˜q™æ ·çš„内存模型就ä¼?x¨¬)有问题åQ?br />¾U¿ç¨‹å·¥ä½œå†…存是独立的åQŒåœ¨å·¥ä½œå†…å­˜A的变量被工作内存B看到需要经˜q‡A-->ä¸Õd†…å­?->B的程度,那么什么时候进行工作内存到ä¸Õd†…存的通信呢?
˜q™é‡Œéœ€è¦æ¶‰å?qi¨¢ng)åˆ?span style="font-size: 40pt;">¾~“存一致性模型,卛_·¥ä½œå†…å­?¾~“å­˜)什么时候刷新和è¯Õd–ä¸Õd†…存必™å»éµå¾ªä¸€å®šçš„规则才可以ã€?
java使用释放一致性模åž?在释æ”ùN”çš„æ—¶å€™å†™å…¥ä¸»å†…å­˜
也就是当synchronized表示的方法或者运行块执行¾l“束时监视器锁释攑֐ŽåQŒé‡Œé¢æ¶‰å?qi¨¢ng)的所有变é‡?局部变量除å¤?的值都写入了主内存åQŒå½“变量被其他线½E‹çœ‹åˆ°çš„话,其值是最新的ã€?br />那么æ–ÒŽ(gu¨©)³•或运行块未进行同步,可能有两斚w¢çš„é—®é¢?
1.æ–ÒŽ(gu¨©)³•的执行顺序是未定çš?br />2.即ä‹Éæ–ÒŽ(gu¨©)³•的执行顺序是相同的,ç”׃ºŽå·¥ä½œå†…存的值未写到ä¸Õd†…存中也有可能有问é¢?br />
thread在jvm当中执行的顺序和代码中看到的™åºåºå¯èƒ½æ˜¯ä¸ä¸€æ ïL(f¨¥ng)š„åQŒäØ“(f¨´)了性能优化½{‰ä»£ç å¯èƒ½è¿›è¡Œé‡æŽ’序åQŒæ‰€æœ‰jmm定义äº?br />¾U¿ç¨‹çš„æ‰§è¡Œé¡ºåºæ¨¡åž‹ï¼š(x¨¬)happens-before模型åQŒè§„则如ä¸?
1.一个线½E‹å½“中,先出现的指ä×o(h¨´)happens-before后出现的指ä×o(h¨´)
2.构造器的里面指令happens-before创徏对象的指ä»?br />3.对于一个监视器åQŒunlock  happens-before 惛_Ž»å¾—é”çš„æŒ‡ä»?br />4.对于volatile的变量,write happens-before read
5.A call to start() on a thread happens-before any actions in the started thread.
6.All actions in a thread happen-before any other thread successfully returns from a
join() on that thread.

happens-before模型保证了JMM内存模型的访问方式ã€?br />对于synchronizedæˆ‘ä»¬å¯ä»¥è®¤äØ“(f¨´)他符合了上面的第3ç‚?br />对于volatile变量åQŒä¿è¯äº†åœ¨çº¿½E‹æ¯‹Æ¡ä¿®æ”¹åŽé©¬ä¸Šåæ˜ åˆîC¸»å†…存当中åQŒä¹Ÿž®±æ˜¯å¯è§æ€§ã€?/div>












1.All instance fields, static fields and array elements are stored in heap memory.存放在java堆内
2.

]]>linux¾Uªå½•http://www.aygfsteel.com/nod0620/articles/358026.htmlnod0620nod0620Wed, 07 Sep 2011 09:46:00 GMThttp://www.aygfsteel.com/nod0620/articles/358026.htmlhttp://www.aygfsteel.com/nod0620/comments/358026.htmlhttp://www.aygfsteel.com/nod0620/articles/358026.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/358026.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/358026.html2.echo,昄¡¤ºæ–‡æœ¬è¡?br />3.whereis command 昄¡¤ºcommand在哪里,whatis command 昄¡¤ºcommand是什ä¹?br />4.free昄¡¤ºå†…存信息
5.history 昄¡¤ºåŽ†å²æŒ‡ä×o(h¨´)
6.locale 昄¡¤ºå½“前¾pȝ»Ÿçš„语­a€è®„¡½®
7.ps 昄¡¤º˜q›ç¨‹æ¶ˆæ¯ã€?ps aux | grep xxx
8.sysctl可以用来讄¡½®æ ¸å¿ƒçš„参敎ͼŒé»˜è®¤çš„æ–‡ä»¶æ˜¯/etc/sysctl.conf
9.top昄¡¤º˜q›ç¨‹æ¶ˆæ¯åQŒä¸»è¦æ˜¯æŸ¥çœ‹¾pȝ»Ÿçš„一些关键性能指标
10.vmstat昄¡¤ºè™šæ‹Ÿå†…å­˜¾lŸè®¡ä¿¡æ¯
11.pgrep 查找½W¦åˆæ¡äšg的进½E?br />12.exit 退出ssh或者终ç«?br />13.pidof 昄¡¤ºå½“前正在˜qè¡Œçš„程序的˜q›ç¨‹id
14.kill PIDåQ›pkill process_nameåQ›killall comm 杀æ­Õd…¨éƒ¨åŒåè¿›½E?br />15.symlinks ½Ž¡ç†å’Œç»´æŠ¤ç¬¦å·é“¾æŽ?br />16.chkconfig 讄¡½®å’Œæ£€æŸ¥ç³»¾lŸçš„æœåŠ¡è®„¡½®
17.查看所有的shell命ä×o(h¨´)åQŒå¯ä»¥è¿›è¡Œä¿®æ”?br />18.export 讄¡½®å’Œæ˜¾½CºçŽ¯å¢ƒå˜é‡?br />19.find 查找文äšg命ä×o(h¨´)
20.wc¾lŸè®¡æ–‡äšg的行敎ͼŒå­—æ•°åQŒå­—节数åQŒæ–‡ä»¶å
21.grep 正则表达式搜ç´?grep xxx æ–‡äšgxxxåQ?i 忽略大小写;-æ•°å­— 昄¡¤ºåŒšw…è¡Œçš„上下数字行;-b 在每行前昄¡¤ºå­—符偏移é‡?-n 昄¡¤ºè¡Œæ•°
22.tar -cvf 压羃;tar -xvf 解压

linux监控åQ?div>http://agapple.iteye.com/blog/1156719
ps详解åQ?
http://blog.chinaunix.net/space.php?uid=20053649&do=blog&id=161862
top详解åQ?br />
http://bbs.linuxtone.org/thread-1684-1-1.html
mpstat
http://hi.baidu.com/kqzjhack/blog/item/20e1bb6744f9dd36aa184c44.html
http://www.ixpub.net/thread-645961-1-1.html


]]>
hashcodehttp://www.aygfsteel.com/nod0620/archive/2011/09/07/358184.htmlnod0620nod0620Wed, 07 Sep 2011 07:11:00 GMThttp://www.aygfsteel.com/nod0620/archive/2011/09/07/358184.htmlhttp://www.aygfsteel.com/nod0620/comments/358184.htmlhttp://www.aygfsteel.com/nod0620/archive/2011/09/07/358184.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/358184.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/358184.html
  • åœ?Java 应用½E‹åºæ‰§è¡ŒæœŸé—´åQŒåœ¨å¯¹åŒä¸€å¯¹è±¡å¤šæ¬¡è°ƒç”¨ hashCode æ–ÒŽ(gu¨©)³•æ—Óž¼Œå¿…须一致地˜q”回相同的整敎ͼŒå‰ææ˜¯å°†å¯¹è±¡˜q›è¡Œ equals 比较时所用的信息没有被修攏V€?
  • 如果æ ÒŽ(gu¨©)® equals(Object) æ–ÒŽ(gu¨©)³•åQŒä¸¤ä¸ªå¯¹è±¡æ˜¯ç›¸ç­‰çš„,那么对这两个对象中的每个对象调用 hashCode æ–ÒŽ(gu¨©)³•都必™åȝ”Ÿæˆç›¸åŒçš„æ•´æ•°¾l“æžœã€?
  • 如果æ ÒŽ(gu¨©)® equals(Object) æ–ÒŽ(gu¨©)³•åQŒä¸¤ä¸ªå¯¹è±¡ä¸ç›¸ç­‰åQŒé‚£ä¹ˆå¯¹˜q™ä¸¤ä¸ªå¯¹è±¡ä¸­çš„ä“Q一对象上调ç”?hashCode æ–ÒŽ(gu¨©)³•不要求一定生成不同的整数¾l“æžœã€?/li>
HashMap使用分离链接法,ž®±æ˜¯åœ¨hashcode冲突的时候在hashcode对应的槽位ä‹É用链表,查找的时候先hashcode扑ֈ°æ§½ä½åQŒç„¶åŽequals()æ–ÒŽ(gu¨©)³•扑ֈ°é“¾è¡¨ä¸­å¯¹åº”的对象ã€?br />jdk的容量是2^n‹Æ¡ï¼Œæ‰‘Öˆ°æ§½ä½ä½¿ç”¨ä½ä¸Žçš„æ–¹å¼ä»£æ›¿æ¨¡çš„æ–¹å¼æé«˜æ€§èƒ½
装蝲因子是装载的对象和hash表æ€ÀL•°é‡çš„æ¯”å€û|¼Œè®îCØ“(f¨´)λåQŒè¿™ä¸ªä»£è¡¨åã^均链表的长度åQŒåœ¨ä¸€‹Æ¡ä¸æˆåŠŸè¦æŸ¥æ‰„¡š„òq›_‡èŠ‚ç‚¹ä¸?br />
λ,一‹Æ¡æˆåŠŸçš„æŸ¥æ‰¾åˆ™äØ“(f¨´)1+λ/2

分离链接法之外还有线性探‹¹‹æ³•å’Œåã^æ–ÒŽ(gu¨©)Ž¢‹¹‹æ³•åQŒåŒæ•£åˆ—½{‰æŽ¢‹¹‹æ³•
探测法不是在冲突的时候利用链表进行存储,而是在冲½Hçš„位置往后查找一个空位置˜q›è¡Œå­˜å‚¨

¾U¿æ€§æŽ¢‹¹‹æ³•ä¼?x¨¬)遇åˆîC¸€‹Æ¡èšç„¦çš„问题åQŒå°±æ˜¯ä¸€ä¸ªå†²½Hçš„位置后面˜qžç®‹çš„位¾|®éƒ½ä¸äØ“(f¨´)½I?br />
那么可以˜q›è¡ŒòqÏx–¹æŽ¢æµ‹æ³•消除一‹Æ¡èšç„¦çš„问题åQŒè™½ç„¶æˆ‘们引˜q›äº†äºŒæ¬¡èšç„¦çš„较?y¨­u)®åª„响的问题åQŒæµè¡Œçš„函数为f(i)=i^2ã€?br />
˜q™ä¸ªæ—¶å€™hash表的定w‡å¿…须为素敎ͼŒ˜q™æ ·åœ¨è¡¨ä¸€åŠäØ“(f¨´)½Iºæ—¶åQŒæ‰èƒ½æ€ÀL•°æ’入一个元ç´?br />如果定w‡ä¸ºéžç´ æ•°çš„æ—¶å€™ï¼Œå¤‡é€‰ä½¾|®è¦ž®‘很å¤?br />
¾|‘上讨论hashmap的个æ•îCØ“(f¨´)素数或è€?^n‹Æ¡é—®é¢˜ï¼Œæ˜¯æ²¡æœ‰åˆ†æ¸…分¼›»é“¾æŽ¥æ³•和探‹¹‹æ³•åQŒåªæœ‰åœ¨æŽ¢æµ‹æ³•的时候,素数才是最有效çš?/div>


]]>™å¹ç›®ž®ç»“http://www.aygfsteel.com/nod0620/archive/2011/08/31/357604.htmlnod0620nod0620Wed, 31 Aug 2011 07:50:00 GMThttp://www.aygfsteel.com/nod0620/archive/2011/08/31/357604.htmlhttp://www.aygfsteel.com/nod0620/comments/357604.htmlhttp://www.aygfsteel.com/nod0620/archive/2011/08/31/357604.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/357604.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/357604.html     

表设è®?/h3>1.求购消息主要是图片和文字的说明,˜q™ä¸ªå…¶å®žå¯ä»¥çœ‹æˆæ˜¯ä¸ªå¾®åšæ¯ä¸ªç”¨æˆ·å‘表feed的表åQŒä½†æœ‰äº›ä¸åŒåQŒè¿™ä¸ªä¸‹æ–‡å†è¯ß_(d¨¢)¼Œ˜q™é‡Œæˆ‘们叫photo表,下面所说的囄¡‰‡ž®±æ˜¯æ±‚购消息ã€?br />考虑到求购消息比较多åQŒæ‰€ä»¥éœ€è¦è¿›è¡Œåˆ†è¡¨ï¼Œå‡è®¾åˆ?个表ã€?strong>ç”׃ºŽä¸šåŠ¡çš„éœ€æ±‚æ˜¯åQšå¯ä»¥æŸ¥çœ‹å•张图片,可以看一个用æˆïL(f¨¥ng)š„囄¡‰‡åˆ—表åQŒé—®é¢˜æ¥äº†ï¼Œæˆ‘们按什么进行分表?
看下表结�


id是图片的idåQŒè¦æŸ¥è¯¢å•张囄¡‰‡çš„话åQŒéœ€è¦èƒ½å¿«é€Ÿçš„定位到哪一张表åQŒè€ŒæŸ¥è¯¢ä¸€ä¸ªç”¨æˆïL(f¨¥ng)š„囄¡‰‡åˆ—表的话åQŒéœ€è¦å¿«é€Ÿæ‰¾åˆ°è¿™ä¸ªç”¨æˆäh‰€æœ‰çš„囄¡‰‡åQŒé‚£ä¹ˆè¿™ä¸ªç”¨æˆïL(f¨¥ng)š„囄¡‰‡åº”该是放åœ?br />一个表里面的,即通过user_id能èµ\由到一张表åQŒä»Žè€Œä»Ž˜q™å¼ è¡¨é‡Œé¢å–得这个用æˆäh‰€æœ‰çš„囄¡‰‡ã€?strong>通过上面分析åQšå¦‚果选择user_id对表数量取模的å€égØ“(f¨´)选择存储的第几个表,
那么一个user_id所有的囄¡‰‡éƒ½åœ¨ä¸€å¼ è¡¨é‡Œé¢äº†ï¼Œ˜q™é‡Œå¯¹idž®±æœ‰è¦æ±‚åQŒidå¯¹è¡¨æ•°é‡å–æ¨¡çš„å€ÆD¦å’Œuser_id对表数量取模的å€ég¸€è‡?ã€?br />˜q™æ ·åšçš„¾l“果是,idçš„å€ég¸æ˜¯è¿ž¾l­çš„åQŒæœ‰äº›è®¸çš„æµªè´¹ï¼Œå¦‚æžœuser_id分布不均的话åQŒå¯¹äºŽæ¯ä¸ªè¡¨çš„æ•°æ®é‡ä¹Ÿä¼š(x¨¬)分布不均

2.评论è¡?br />对图片进行评论,对于单个囄¡‰‡æ¥è¯´æœ‰è¯„论列表,对于单个用户来说åQŒä»–能看到所有对他图片进行评论的评论列表åQŒæ‰€ä»¥é‡‡ç”¨äº†ä¸¤å¥—表的æ–ÒŽ(gu¨©)¡ˆåQŒå¯¹äºŽç”¨photo_id分表çš?br />çš„comment表,以及(qi¨¢ng)针对user_id分表的comment_uè¡?br />

3.好友关系è¡?br />˜q™ä¸ª¾cÖM¼¼äºŽå¾®è–„里面的å…Ïx³¨æˆ–者粉丝表,å’Œè¯„è®ø™¡¨ä¸€æ øP¼Œ˜q™é‡Œéœ€è¦ä¸¤å¥—表åQŒä¸€ä¸ªæ˜¯å…Ïx³¨è¡¨ï¼Œä¸€ä¸ªæ˜¯¾_‰ä¸è¡?br />

Feed‹¹?/h3>当一个ähå…Ïx³¨å¦å¤–一个äh的时候,那么被关注的人发表的囄¡‰‡æ˜¯èƒ½è¢«å¦å¤–一个äh看到的,˜q™å’Œå¾®åšçš„feed‹¹æ˜¯ä¸€æ ïL(f¨¥ng)š„ã€?br />˜q™é‡Œæœ‰ä¸¤¿Uæ–¹å¼å®žçŽŽÍ¼Œpush模式(推模å¼?åQŒpull模式(拉模å¼?。push模式åQšå½“一个用户发表图片的时候,‹‚€ç´¢è¿™ä¸ªç”¨æˆïL(f¨¥ng)š„
¾_‰ä¸è¡¨ï¼Œä¸ºæ¯ä¸ªç²‰ä¸æ’入一条feed。pull模式åQšå½“一个用户发表图片的时候,只是存一份数据,当一个用æˆähŸ¥çœ‹ä»–的关注的用户的feed的时候,需要先‹‚€ç´¢å…³æ³¨è¡¨åQŒç„¶åŽæ£€ç´¢æ¯ä¸€ä¸ªå…³æ³¨ç”¨æˆähœ‰æ²¡æœ‰æ–°å‘çš„feedã€?br />
pushå’Œpull模式各有利弊åQŒå½“使用push模式的时候,如果一个用æˆ?名äh)的粉丝过多的话,那么每个¾_‰ä¸æ’入一条feed对存储的压力ž®±å¤ªå¤§äº†(100000¾_‰ä¸è¯ï¼Œæ’å…¥100000)åQŒå­˜å‚¨ç©ºé—´æµªè´¹ä¹Ÿéžå¸¸çš„严重ã€?br />pull模式的话åQŒå¦‚果一个用户关注过多的时候,查询该用æˆïL(f¨¥ng)š„å…Ïx³¨åˆ—表也是有很大的代ä­h(hu¨¢n)çš?br />
™å¹ç›®ç”¨çš„æ˜¯pull模式åQŒæ³¨æ„åˆ°æ±‚è´­™å¹ç›®çš„特ŒDŠæ€§ï¼Œä¸€èˆ¬åªæ˜¯çœ‹æœ€æ–°çš„æ±‚购的消息,假设某个用户当前æœ?000条新feedåQŒè¿™ä¸ªç”¨æˆ·ä¹Ÿä¸èƒ½å®Œå…¨çš„看完,所以认为只要取得最新的消息里面的若òq²æ¡åQŒå…¶ä½™çš„æ¶ˆæ¯çš„话可以在历史feed列表里面看到或者下一‹Æ¡çœ‹åˆŽÍ¼Œ˜q™é‡Œž®±æœ‰ä¸ªtimeline的概å¿üc(di¨£n)€‚当‹Æ¡å–得最新消息后åQŒéœ€è¦æŠŠ˜q™ä¸ªæ—‰™—´ç‚¹ä¿å­˜ï¼Œä¸‹æ¬¡æŸ¥è¯¢çš„æ—¶å€™ï¼Œä»Žè¿™ä¸ªæ—¶é—´ç‚¹˜q›è¡ŒæŸ¥è¯¢ã€?br />
™å¹ç›®å…·ä½“的做法:(x¨¬)
1.查询用户的关注列�br />2.从cache中取出timeline
3.timeline为空的话åQŒç›´æŽ¥å–出旧的feed 30条,更新timelineåQŒå…¶ä¸­æœ€æ–°çš„一条的创徏旉™—´ä¸ºtimeline
4.timelineä¸äØ“(f¨´)½Iºçš„话,取得timeline之后的feedåQŒæœ€å¤§å€égØ“(f¨´)30条,查过30条,取得的是最旧的30条,更新timelineåQŒå…¶ä¸­æœ€æ–°çš„一条的创徏旉™—´ä¸ºtimelineã€?br />

½W?步其实和微博的做法是不同的,假设æœ?000条feedåQŒå¾®åšæ˜¯ä¸€‹Æ¡æ€§åˆ·å‡ºæ¥åQŒè€Œè¿™ä¸ªæ˜¯ä¸€‹Æ¡åˆ·å‡?0条,˜q™é‡Œæœ‰ä¸ªåšå¼ˆåœ¨é‡Œé¢ï¼š(x¨¬)
一‹Æ¡åˆ·æ–?0条,åˆäh–°çš„æ¬¡æ•°å¤šäº†ï¼ŒæŸ¥è¯¢å¤šäº†åQŒä½†æ˜¯ä¸€‹Æ?000条的单次查询压力大了åQŒè¿˜æœ‰å¤šž®‘äh看了30条之后ç‘ô¾l­åˆ·æ–°çœ‹çš„? 所以我们采取降低单‹Æ¡åˆ·æ–°çš„代ä­h(hu¨¢n)åQŒè¿™æ ·å¯¹æœåŠ¡å™¨å³°å€¼çš„åŽ‹åŠ›ä¹Ÿå°±ä¸‹æ¥äº?br />

其它

˜q˜æœ‰å¾ˆå¤šä¼˜åŒ–的点没有说出来,比如路由表取模的时候,是用位与操作çš?18%16==18&15)
˜q˜æœ‰å„个能用到cache的地方尽量ä‹É用cacheåQŒå¯¹äºŽè¯»å†™çš„话,可以增加è¯Õd†™é˜Ÿåˆ—.
对于扩展åQŒæ€§èƒ½åQŒåŽ¾l­è€ƒè™‘的:(x¨¬)
当单个用户关注数­‘…过一定数目,˜q™ä¸ªç”¨æˆ·ž®±éœ€è¦ç‰¹åˆ«çš„对待åQŒæ¯”如用户关注单独的变成一张表åQŒå‡ž®‘关注表的压åŠ?br />对用æˆäh´»è·ƒåº¦˜q›è¡Œåˆ†æžåQŒæ´»è·ƒç”¨æˆïL(f¨¥ng)š„feed使用pullå’Œpush模式相结合的模式
对于¾_‰ä¸æ•°å¾ˆå¤šçš„用户åQŒå¯ä»¥å•独成表,发的feed可以先push¾l™ä¸€éƒ¨åˆ†ç”¨æˆ·åQŒè®©ä¸€éƒ¨åˆ†ç”¨æˆ·å…ˆçœ‹åˆ°feed.








nod0620 2011-08-31 15:50 发表评论
]]>二叉查找æ ?w¨¨i)复习(f¨¤n)简è®?/title><link>http://www.aygfsteel.com/nod0620/archive/2011/08/29/357301.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Mon, 29 Aug 2011 09:38:00 GMT</pubDate><guid>http://www.aygfsteel.com/nod0620/archive/2011/08/29/357301.html</guid><wfw:comment>http://www.aygfsteel.com/nod0620/comments/357301.html</wfw:comment><comments>http://www.aygfsteel.com/nod0620/archive/2011/08/29/357301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/nod0620/comments/commentRss/357301.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/nod0620/services/trackbacks/357301.html</trackback:ping><description><![CDATA[<h3>remove</h3><p>remove分成三种情况åQŒæ²¡æœ‰å­©å­èŠ‚ç‚¹çš„èŠ‚ç‚¹(即页å­?,单个孩子节点的节点,两个孩子节点的节ç‚?/p><p>1)™åµå­èŠ‚ç‚¹å¯ä»¥ç›´æŽ¥åˆ é™¤</p><p>2)单个孩子节点的节点删除了åQŒè®©å…¶ä¸‹çš„孩子节点直接和其父亲节点相˜q?ž®±æ˜¯å­©å­èŠ‚ç‚¹å’Œç¥–çˆ¶èŠ‚ç‚¹ç›¸˜q?</p><p>3)两个孩子节点的节点,ä¸ÞZº†ä¿æŒæŽ’序状态,需要拿到这个节点的左子æ ?w¨¨i)的最大节ç‚ÒŽ(gu¨©)ˆ–者右子树(w¨¨i)的最ž®èŠ‚ç‚¹ï¼Œå¾—åˆ°˜q™ä¸ªèŠ‚ç‚¹çš„æ•°æ®ä»£æ›¿è¦åˆ é™¤çš„èŠ‚ç‚¹ï¼Œ</p><p>然后删除˜q™ä¸ªå·¦å­æ ?w¨¨i)的最大节ç‚ÒŽ(gu¨©)ˆ–者右子树(w¨¨i)的最ž®èŠ‚ç‚¹ï¼Œå› äØ“(f¨´)左子æ ?w¨¨i)的最大节ç‚ÒŽ(gu¨©)²¡æœ‰å³èŠ‚ç‚¹(有右节点的话åQŒä»–ž®×ƒ¸æ˜¯æœ€å¤§çš„äº?,同理åQŒå³å­æ ‘(w¨¨i)的最ž®èŠ‚ç‚?/p><p>没有左节点,所以要删除的这个节点只有一个或者没有孩子节点,只需要进è¡?)或è€?)ž®±å®Œæˆäº†ã€?/p><p> </p><div><br /><h3>AVLæ ?/h3></div><br /><p> </p><p>在插入节ç‚ÒŽ(gu¨©)—¶é€šè¿‡æ—‹è{(rotation)解决问题:</p><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;">  </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * æ’入一个元素到æ ?w¨¨i)里面,可能破坏了高度差åQŒéœ€è¦æ‰¾åˆîC¸€ä¸ªèŠ‚ç‚¹aåQŒè¯¥èŠ‚ç‚¹å·¦å­æ ?w¨¨i)和叛_­æ ?w¨¨i)被破坏了,则需要对˜q™ä¸ªèŠ‚ç‚¹(òqŒ™¡¡å› å­)<br />     * <br />     * æ ?w¨¨i)进行åã^衡,有四¿Uæƒ…å†?<br />     * <br />     * 1.a节点的左儿子的左子树(w¨¨i)插入<br />     * <br />     * 2.a节点的左儿子的右子树(w¨¨i)插入<br />     * <br />     * 3.a节点的右儿子的左子树(w¨¨i)插入<br />     * <br />     * 4.a节点的右儿子的右子树(w¨¨i)插入<br />     * <br />     * <br />     * 1.4两种情况需要进行一‹Æ¡æ—‹è½?br />     * <br />     * 2.3两种情况需要进行两‹Æ¡æ—‹è½?br />     *<br />     * æ—‹è{的目的是ä¸ÞZº†ä½¿æ’入节点的æ ?w¨¨i)的高度降ä½?åQŒæ‰€ä»¥åªè¦æ±‚æ—‹è{òqŒ™¡¡å› å­ä¸ºæ ¹çš„æ ‘(w¨¨i)ž®±å¯ä»¥äº†<br />    </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /></span></div><p><br /></p>在删除节点的时候:(x¨¬)<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;">    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * åˆ é™¤ä¸€ä¸ªèŠ‚ç‚¹ï¼Œæ‰‘Öˆ°òqŒ™¡¡å› å­åQŒä»–的左子树(w¨¨i)高度和右子树(w¨¨i)高度如果相差2的话åQŒå°±éœ€è¦æ—‹è½¬ï¼Œè€Œä¸”æ—‹è{后,òqŒ™¡¡å› å­çš„èŠ‚ç‚¹äØ“(f¨´)根的æ ?w¨¨i)的高度肯定ä?br />     * <br />     * ä¸‹é™1åQŒè¿™æ ·åã^衡因子所在的æ ?w¨¨i)的高度下é™?åQŒä¹Ÿæœ‰å¯èƒ½éœ€è¦è¿›è¡Œæ—‹è½¬è°ƒæ•ß_(d¨¢)¼Œ˜q™æ ·è°ƒæ•´ä¸€ç›´åˆ°æ ¹èŠ‚ç‚?br />     * <br />     </span><span style="color: #008000;">*/</span></div><br /><h3>代码如下åQ?br /></h3><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff;">package</span><span style="color: #000000;"> struct;<br /><br /><br /></span><span style="color: #008000;">/**</span><span style="color: #008000;"><br /> * </span><span style="color: #808080;">@author</span><span style="color: #008000;"> chenxiaohui<br /> * </span><span style="color: #808080;">@version</span><span style="color: #008000;"> åˆ›å¾æ—‰™—´åQ?011-8-26<br /> * <br /> * <br /> </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /></span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> AvlTree {<br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * <br />     * avlæ ?æ ?w¨¨i)中每个节点的左子æ ?w¨¨i)和右子树(w¨¨i)的高度最多差1的二叉查找树(w¨¨i)<br />     * <br />     * <br />     * <br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> height(AvlNode node) {<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> node </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;"> </span><span style="color: #000000;">?</span><span style="color: #000000;"> node.height : </span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * <br />     * <br />     * æ’入一个元素到æ ?w¨¨i)里面,可能破坏了高度差åQŒéœ€è¦æ‰¾åˆîC¸€ä¸ªèŠ‚ç‚¹aåQŒè¯¥èŠ‚ç‚¹å·¦å­æ ?w¨¨i)和叛_­æ ?w¨¨i)被破坏了,则需要对˜q™ä¸ªèŠ‚ç‚¹(òqŒ™¡¡å› å­)<br />     * <br />     * æ ?w¨¨i)进行åã^衡,有四¿Uæƒ…å†?<br />     * <br />     * 1.a节点的左儿子的左子树(w¨¨i)插入<br />     * <br />     * 2.a节点的左儿子的右子树(w¨¨i)插入<br />     * <br />     * 3.a节点的右儿子的左子树(w¨¨i)插入<br />     * <br />     * 4.a节点的右儿子的右子树(w¨¨i)插入<br />     * <br />     * <br />     * 1.4两种情况需要进行一‹Æ¡æ—‹è½?br />     * <br />     * 2.3两种情况需要进行两‹Æ¡æ—‹è½?br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> t<br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> tree<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> AvlNode insert(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> t, AvlNode tree) {<br /><br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (tree </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;">return</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> AvlNode(t);<br /><br />        </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> cmp </span><span style="color: #000000;">=</span><span style="color: #000000;"> compare(t, tree.element);<br /><br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (cmp </span><span style="color: #000000;"><</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> å·¦å­æ ?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">            tree.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> insert(t, tree.leftChild);<br /><br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> å› äØ“(f¨´)左子æ ?w¨¨i)插入了节点åQŒé‚£ä¹ˆå·¦å­æ ‘(w¨¨i)比右子树(w¨¨i)é«?æ ÒŽ(gu¨©)®a(ch¨£n)vlæ ?w¨¨i)的性质åQŒæ’入了节点<br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> è¦ä¹ˆé«˜åº¦å·®äØ“(f¨´)1åQŒè¦ä¹ˆé«˜åº¦å·®ä¸?åQŒæ‰€ä»¥å½“相差ä¸?æ—Óž¼Œéœ€è¦è¿›è¡Œæ ‘(w¨¨i)的调æ•?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ((height(tree.leftChild) </span><span style="color: #000000;">-</span><span style="color: #000000;"> height(tree.reightChild)) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">2</span><span style="color: #000000;">) {<br /><br />                </span><span style="color: #008000;">//</span><span style="color: #008000;"> å½“t比树(w¨¨i)左子æ ?w¨¨i)的元素˜q˜å°çš„话åQŒå°±æ˜¯åœ¨æ ?w¨¨i)的左子树(w¨¨i)的左边插入节点åQŒæˆä¸ºå·¦å­æ ‘(w¨¨i)的左子树(w¨¨i)åQŒéœ€è¦ä¸€‹Æ¡æ—‹è½?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (compare(t, tree.leftChild.element) </span><span style="color: #000000;"><</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br /><br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateLeftChild(tree);<br />                } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br />                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> å½“t比树(w¨¨i)左子æ ?w¨¨i)的元素˜q˜å¤§çš„话åQŒå°±æ˜¯åœ¨æ ?w¨¨i)的左子树(w¨¨i)的双™¾¹æ’入节点åQŒæˆä¸ºå·¦å­æ ‘(w¨¨i)的右子树(w¨¨i)åQŒéœ€è¦ä¸¤‹Æ¡æ—‹è½?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> doubleRotateLeftChild(tree);<br />                }<br />            }<br /><br />        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (cmp </span><span style="color: #000000;">></span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> å›_­æ ?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">            tree.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> insert(t, tree.reightChild);<br /><br />            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ((height(tree.reightChild) </span><span style="color: #000000;">-</span><span style="color: #000000;"> height(tree.leftChild)) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">2</span><span style="color: #000000;">) {<br />                </span><span style="color: #008000;">//</span><span style="color: #008000;"> å½“t比树(w¨¨i)叛_­æ ?w¨¨i)的元素˜q˜å¤§çš„话åQŒå°±æ˜¯åœ¨æ ?w¨¨i)的叛_­æ ?w¨¨i)的双™¾¹æ’入节点åQŒæˆä¸ºå³å­æ ‘(w¨¨i)的右子树(w¨¨i)åQŒéœ€è¦ä¸€‹Æ¡æ—‹è½?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (compare(t, tree.reightChild.element) </span><span style="color: #000000;">></span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateRightChild(tree);<br />                } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br />                    </span><span style="color: #008000;">//</span><span style="color: #008000;"> å½“t比树(w¨¨i)叛_­æ ?w¨¨i)的元素˜q˜å°çš„话åQŒå°±æ˜¯åœ¨æ ?w¨¨i)的叛_­æ ?w¨¨i)的左边插入节点åQŒæˆä¸ºå³å­æ ‘(w¨¨i)的左子树(w¨¨i)åQŒéœ€è¦ä¸¤‹Æ¡æ—‹è½?/span><span style="color: #008000;"><br /></span><span style="color: #000000;">                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> doubleRotateRightChild(tree);<br />                }<br />            }<br /><br />        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> æ ?w¨¨i)里面有˜q™ä¸ªæ ?/span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />        }<br />        tree.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math<br />                .max(height(tree.leftChild), height(tree.reightChild)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> tree;<br /><br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * ½W?¿Uæƒ…况需要进行顺旉™’ˆæ—‹è{(åÏx—‹è½?<br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> k2<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode rotateLeftChild(AvlNode k2) {<br /><br />        AvlNode k1 </span><span style="color: #000000;">=</span><span style="color: #000000;"> k2.leftChild;<br /><br />        k2.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> k1.reightChild;<br />        k1.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> k2;<br /><br />        k2.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math.max(height(k2.leftChild), height(k2.reightChild)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        k1.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math.max(height(k1.leftChild), height(k2)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> k1;<br /><br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * <br />     * ½W?¿Uæƒ…况需要进行逆时针旋è½?左旋è½?<br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> k2<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode rotateRightChild(AvlNode k2) {<br /><br />        AvlNode k1 </span><span style="color: #000000;">=</span><span style="color: #000000;"> k2.reightChild;<br /><br />        k2.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> k1.leftChild;<br />        k1.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> k2;<br /><br />        k2.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math.max(height(k2.leftChild), height(k2.reightChild)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        k1.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math.max(height(k1.reightChild), height(k2)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> k1;<br /><br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * ½W?¿Uæƒ…况需要进è¡?å?左旋è½?<br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> k3<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode doubleRotateLeftChild(AvlNode k3) {<br />        AvlNode k1 </span><span style="color: #000000;">=</span><span style="color: #000000;"> k3.leftChild;<br />        k3.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateRightChild(k1);<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> rotateLeftChild(k3);<br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * ½W?¿Uæƒ…况需要进è¡?å·?åÏx—‹è½?<br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> k3<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /><br />    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode doubleRotateRightChild(AvlNode k3) {<br />        AvlNode k1 </span><span style="color: #000000;">=</span><span style="color: #000000;"> k3.reightChild;<br />        k3.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateLeftChild(k1);<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> rotateRightChild(k3);<br />    }<br /><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> compare(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> a, </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> b) {<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> a </span><span style="color: #000000;">-</span><span style="color: #000000;"> b;<br />    }<br /><br />    </span><span style="color: #0000ff;">static</span><span style="color: #000000;"> </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> AvlNode {<br /><br />        </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> element;<br />        </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> height;<br />        </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode leftChild;<br />        </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> AvlNode reightChild;<br /><br />        AvlNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> element) {<br />            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">(element, </span><span style="color: #0000ff;">null</span><span style="color: #000000;">, </span><span style="color: #0000ff;">null</span><span style="color: #000000;">);<br />        }<br /><br />        AvlNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> element, AvlNode left, AvlNode right) {<br />            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.element </span><span style="color: #000000;">=</span><span style="color: #000000;"> element;<br />            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> left;<br />            </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> right;<br />        }<br /><br />    }<br /><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> sysout(AvlNode node) {<br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (node </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br /><br />            AvlNode a </span><span style="color: #000000;">=</span><span style="color: #000000;"> node.leftChild;<br />            sysout(a);<br />            </span><span style="color: #0000ff;">for</span><span style="color: #000000;"> (</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> i </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">; i </span><span style="color: #000000;"><</span><span style="color: #000000;"> node.height; i</span><span style="color: #000000;">++</span><span style="color: #000000;">) {<br />                System.out.print(</span><span style="color: #000000;">"</span><span style="color: #000000;">     </span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />            }<br />            System.out.print(node.element);<br />            System.out.print(</span><span style="color: #000000;">"</span><span style="color: #000000;">\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />            AvlNode b </span><span style="color: #000000;">=</span><span style="color: #000000;"> node.reightChild;<br />            sysout(b);<br />        }<br />    }<br /><br />    </span><span style="color: #008000;">/**</span><span style="color: #008000;"><br />     * åˆ é™¤ä¸€ä¸ªèŠ‚ç‚¹ï¼Œæ‰‘Öˆ°òqŒ™¡¡å› å­åQŒä»–的左子树(w¨¨i)高度和右子树(w¨¨i)高度如果相差2的话åQŒå°±éœ€è¦æ—‹è½¬ï¼Œè€Œä¸”æ—‹è{后,òqŒ™¡¡å› å­çš„èŠ‚ç‚¹äØ“(f¨´)根的æ ?w¨¨i)的高度肯定ä?br />     * <br />     * ä¸‹é™1åQŒè¿™æ ·åã^衡因子所在的æ ?w¨¨i)的高度下é™?åQŒä¹Ÿæœ‰å¯èƒ½éœ€è¦è¿›è¡Œæ—‹è½¬è°ƒæ•ß_(d¨¢)¼Œ˜q™æ ·è°ƒæ•´ä¸€ç›´åˆ°æ ¹èŠ‚ç‚?br />     * <br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> t<br />     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> tree<br />     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"><br />     </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> AvlNode delete(</span><span style="color: #0000ff;">int</span><span style="color: #000000;"> t, AvlNode tree) {<br /><br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (tree </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;">return</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br /><br />        </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> cmp </span><span style="color: #000000;">=</span><span style="color: #000000;"> compare(t, tree.element);<br /><br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (cmp </span><span style="color: #000000;"><</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />            tree.leftChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> delete(t, tree.leftChild);<br /><br />            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ((height(tree.reightChild) </span><span style="color: #000000;">-</span><span style="color: #000000;"> height(tree.leftChild)) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">2</span><span style="color: #000000;">) {<br />                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (tree.leftChild </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateRightChild(tree);<br />                } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> doubleRotateRightChild(tree);<br /><br />                }<br /><br />            }<br />        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (cmp </span><span style="color: #000000;">></span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />            tree.reightChild </span><span style="color: #000000;">=</span><span style="color: #000000;"> delete(t, tree.reightChild);<br /><br />            </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> ((height(tree.leftChild) </span><span style="color: #000000;">-</span><span style="color: #000000;"> height(tree.reightChild)) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">2</span><span style="color: #000000;">) {<br />                </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (tree.reightChild </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> rotateLeftChild(tree);<br />                } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {<br />                    tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> doubleRotateLeftChild(tree);<br />                }<br />            }<br />        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (cmp </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">0</span><span style="color: #000000;">) {<br />            tree </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />        }<br /><br />        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (tree </span><span style="color: #000000;">!=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">null</span><span style="color: #000000;">) {<br />            tree.height </span><span style="color: #000000;">=</span><span style="color: #000000;"> Math.max(height(tree.leftChild),<br />                    height(tree.reightChild)) </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />        }<br />        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> tree;<br /><br />    }<br /><br />    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> </span><span style="color: #0000ff;">static</span><span style="color: #000000;"> </span><span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {<br />        AvlTree avlTree </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> AvlTree();<br />        AvlNode node </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> AvlNode(</span><span style="color: #000000;">20</span><span style="color: #000000;">);<br />        </span><span style="color: #008000;">/*</span><span style="color: #008000;"><br />         * Random random = new Random(); for (int i = 0; i < 10; i++) { int y =<br />         * random.nextInt(100) + 1; node = avlTree.insert(y, node); }<br />         </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /><br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">8</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">3</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">10</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">2</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">5</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">30</span><span style="color: #000000;">, node);<br /><br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">50</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">6</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">20</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">35</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">43</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">60</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">18</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">26</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">33</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">40</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">45</span><span style="color: #000000;">, node);<br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.insert(</span><span style="color: #000000;">62</span><span style="color: #000000;">, node);<br /><br />        </span><span style="color: #008000;">//</span><span style="color: #008000;"> avlTree.sysout(node);</span><span style="color: #008000;"><br /></span><span style="color: #000000;"><br />        node </span><span style="color: #000000;">=</span><span style="color: #000000;"> avlTree.delete(</span><span style="color: #000000;">2</span><span style="color: #000000;">, node);<br />        avlTree.sysout(node);<br /><br />    }<br />}<br /></span></div><br /><h3> </h3><img src ="http://www.aygfsteel.com/nod0620/aggbug/357301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/nod0620/" target="_blank">nod0620</a> 2011-08-29 17:38 <a href="http://www.aygfsteel.com/nod0620/archive/2011/08/29/357301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>classloader记录http://www.aygfsteel.com/nod0620/archive/2011/08/24/357127.htmlnod0620nod0620Wed, 24 Aug 2011 02:40:00 GMThttp://www.aygfsteel.com/nod0620/archive/2011/08/24/357127.htmlhttp://www.aygfsteel.com/nod0620/comments/357127.htmlhttp://www.aygfsteel.com/nod0620/archive/2011/08/24/357127.html#Feedback0http://www.aygfsteel.com/nod0620/comments/commentRss/357127.htmlhttp://www.aygfsteel.com/nod0620/services/trackbacks/357127.html
一般是如上囄¡»“æž?br />
Bootstrap ClassLoader/启动¾cÕdŠ è½½å™¨
ä»–çš„parent为null, 主要负责'sun.boot.class.path'¾pȝ»Ÿå±žæ€§æŒ‡å®šçš„ æˆ?-Xbootclasspath 选项指定的jar包装入工ä½?
Bootstrap ClassLoader是jvm控制的,不是java语言层面¾~–写的,默认加蝲jdk_home/jre/lib/下面的jar包和其他相关的东西,如jdk的核心包rt.jarž®±æ˜¯åœ¨è¿™é‡Œè¢«åŠ è²çš?br />
Extension ClassLoader/扩展¾cÕdŠ è½½å™¨
主要负责jdk_home/jre/lib/ext目录ä¸?'java.ext.dirs'¾pȝ»Ÿå±žæ€§æŒ‡å®?çš„jar包或 -Djava.ext.dirs 指定目录下的jar包装入工ä½?ä»–çš„parentä¸?Bootstrap ClassLoader

System ClassLoader/¾pȝ»Ÿ¾cÕdŠ è½½å™¨
主要负责java -classpath/-Djava.class.path所指的目录下的¾cÖM¸Žjar包装入工ä½?一般我们会(x¨¬)配置环境变量classpathåQŒè¿™ä¸ªå°±æ˜¯è²å…¥classpath指定的èµ\径下jarå’Œclass,
òq›_¸¸æˆ‘们指定一ä¸?."åøP¼Œž®±æ˜¯æŒ‡å®šä»Žå½“前目录下开始搜索class¾c?parentä¸?Extension ClassLoader.

User Custom ClassLoader/用户自定义类加蝲å™?java.lang.ClassLoader的子¾c?
在程序运行期é—? 通过java.lang.ClassLoader的子¾cÕdŠ è½½classæ–‡äšg.


classloader要加载class先从底向上传递给父亲加蝲¾c»ï¼Œæœ€™å¶å±‚çš„classloader如果能够加蝲ž®±åŠ è½½è¿›æ¥ï¼Œä¸è¡Œçš„è¯åQŒå°±è‡ªä¸Šè€Œä¸‹ä¼ é€’,只到一个classloader能进行类的加载,
如果没有一个classloader能加载的话,ž®×ƒ¼š(x¨¬)抛出ClassNotFoundException或者NoClassDefFoundError异常åQŒè¿™ä¸ªå°±æ˜¯åŒäº²å§”‹z¾æ¨¡å¼?br />
classloader˜q™ç§æ¨¡å¼ä¿è¯äº†ä¸åŒçš„classloader之间¾cÖM¸ä¼?x¨¬)相互的影响åQŒé‚£ä¹ˆä¹Ÿä¿è¯äº†å¥½çš„类不会(x¨¬)被恶意的¾cÀL‰€ç ´ååQŒè¿™ä¸ªä¹Ÿæ˜¯jvm沙箱模式安全的一个保è¯?br />
在不同classloader的同名的¾cÕd®žä¾‹ä¸èƒ½äº’相沟通,¾cÕdž‹è½¬æ¢åQŒinstanceofåQŒå¦‚果这样做åQŒåˆ™ä¼?x¨¬)抛出ClassCastException.所以抛出ClassCastException的原因不止和¾l§æ‰¿åQŒå®žçŽ°æœ‰å…³ç³»åQ?br />˜q˜å’Œclassloader有关¾p?

当运行时发现一个新class要loadæ—Óž¼Œé™¤ä»£ç å·²æŒ‡å®šç”±å“ªclassloader的实例load外,先由调用者的classloader所在的classloader tree去loadåQŒå¦‚æžœsuper¾c?interface¾cÕd¯¹äºŽè¿™ä¸ªæ ‘(w¨¨i)是新的也一起会(x¨¬)被load。这是caller classloader的概å¿?
双亲委派可以被打ç ß_(d¨¢)¼Œå…¨æƒè´Ÿè´£ä¹Ÿå¯è¢«æ‰“ç ß_(d¨¢)¼Œæ‰€ä»¥è¿è¡Œæ—¶å†›_®š¾cÀL¥è‡ªå“ªé‡Œï¼Œ˜q˜æ˜¯ç”±classloaderæ ?w¨¨i)å’Œload class的代码是怎样而决定ã€?br />

Thread Context ClassLoaderåQšçº¿½E‹ä¸Šä¸‹æ–‡classloaderåQŒæ˜¯hold住了一ClassLoader的实例,˜q™ä¸ªholder在线½E‹è¿è¡Œæµ½E‹é‡Œå¯ä»¥åˆ°è¾¾éšå¼ä¼ é€’classloader。这个classloader是一个不ä¼?x¨¬)主动load的实例,ž®±æ˜¯è¯´åœ¨˜q™ä¸ª¾U¿ç¨‹˜qè¡Œä¸‹é‡åˆ°æ–°¾c»è¿™ä¸ªclassloader不会(x¨¬)ä¸ÕdŠ¨åŽ»loadåQŒåªæœ‰è‡ªå·Þq”¨æ˜‘Ö¼ä»£ç æˆ–你看不见的jar里用昑ּä»£ç ç”¨è¿™ä¸?div>classloader loadClass()或Class.forName()åQŒæ‰ä¼?x¨¬)生效。因此,caller classloaderå’?thread context classloaderåQŒåœ¨æ‰§è¡ŒåˆîC½ çš„代码时åQŒå·²å®šã€‚åÆˆä¸”æ‰§è¡Œæµ½E‹çš„不同åQŒåˆ°ä½ ä»£ç æ—¶çš„入口也不同åQŒè¢«æ”„¡½®å…¥threadçš„thread context classloaderå’ŒCaller ClassLoaderä¸ä¸€å®šä¸€æ øP¼Œå› æ­¤æ˜¯ä¸½E›_®šçš?br />
需要稳定的话,ž®Þp¦ä¿è¯åœ¨è®¾è®¡æ—¶ž®Þp€ƒè™‘到各¿Uå…¥å£å’Œç”¨æ³•的情况,然后得到¼‹®å®šçš„classloader存在 thread context classloader或者第三方的class loader中,tomcat的类加蝲体系ž®±æ˜¯˜q™æ ·åšçš„.



nod0620 2011-08-24 10:40 发表评论
]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º а²ÏØ| ÔÀÎ÷ÏØ| ̨ÍåÊ¡| Т¸ÐÊÐ| °×ÀÊÏØ| êùÎªÏØ| ½­»ª| Õ¿½­ÊÐ| ¹ÌÕòÏØ| ÁÙ¸ßÏØ| °²Ë³ÊÐ| Ù¤Ê¦ÏØ| ÈýÃÅÏØ| À´°²ÏØ| °ËËÞÏØ| ·À³Ç¸ÛÊÐ| Ó¯½­ÏØ| »·áÏØ| ʯÃÅÏØ| ÀäË®½­ÊÐ| Ö£ÖÝÊÐ| ËæÖÝÊÐ| ÅíÔóÏØ| º£ÃÅÊÐ| Í­´¨ÊÐ| ×ÊÔ´ÏØ| °¢À­ÉÆÃË| Ëà±±| ±±º£ÊÐ| ÁÙÕÄÏØ| ÑôȪÊÐ| ¸¢ÁêÇø| Î÷¹±Çø| ½¨ÄþÏØ| Ëþ³ÇÊÐ| ïö¹éÏØ| Îä¸ÔÊÐ| ¿ªÑôÏØ| ÀÈ·»ÊÐ| ͨÐíÏØ| ³çÈÊÏØ|