??xml version="1.0" encoding="utf-8" standalone="yes"?>中文亚洲欧美,国产精品成人品,国产欧美午夜http://www.aygfsteel.com/nod0620/zh-cnWed, 25 Jun 2025 01:45:13 GMTWed, 25 Jun 2025 01:45:13 GMT60java io以及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阅读全文

nod0620 2011-09-29 13:15 发表评论
]]>
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[     摘要: 囑ַҎU程池的cȝ构,双是放入线E池执行的Q务类l构ExecutorServiceExecutorService定义了线E池的基本的ҎQAbstractExecutorService是个抽象c,实现了ExecutorService的部分,主要是实C几个submit()Ҏ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的具体实玎ͼ其具体的实现都是ZAQS实现?br />
ReentrantLock
ReentrantLock是可重入的互斥锁Q重Ҏ重入和互斥,ReentrantLock 由最q成功获得锁的线E所持有Q当q个U程再次试拥有q个Lock时就是重入。互斥就?br />在某一旉只有一个线E能持有Lock?br />    public void lock() {
        sync.lock();
    }
获得锁方法,Sync是AQS的抽象子c,实现可重入和互斥的大部分功能。在Sync的子cM有FairSync和NonfairSync两种代表公^锁策略和非公q锁{略

Sync lockҎ留给子类d玎ͼNonfairSync的实玎ͼ
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
不管是不是有其他U程在AQS的阻塞的队列里面Q如果当前线E能获得U程Q就直接获得U程Q不行的话执行AQS的acquire()ҎQ基本就是进入阻塞队列的命了?br />关键?AQS的acquire()中调用的tryAcquire(int arg)是留l子cd现的Q是在进入阻塞队列前再尝试一ơ获取锁(lock()Ҏ到这个点上面可能其他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;
        }
关键?Qstate?Q没有线E请求锁Q直接分配给本线E?br />关键?.  如果本线E已l得到锁Qstate?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机会,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被减后还不ؓ0Q表C个锁被一个线E重入后q没有完全释放,release()Ҏ后面不会执行Q也是不会执行unparkd队列中的U程.


ReentrantReadWriteLock
ReentrantReadWriteLock内部有两个锁Q互斥可重入的WriteLock和共享的ReadLock
内部实现中state字段的高16位代表的是read countQ低16位代表的是write count
AQS的实C有NonfairSync和FairSync之分Q?br />主要区别是同时有dU程时候对待读写线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永远都不dQread的话看阻塞队列header之后的node是不是write的,如果是就dQ可以避免read一直运行导致的write饥饿?br />FairSyncQ?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其中会执行留给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持有锁,判断是否需要阻塞读hQ之后原子更新read count
3.上面成功后就q回1Q不成功的话在@环中试着dQ?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Ҏ是read count ?Q然后查看阻塞队列有没有U程需要unpark

WriteLock的实现和ReetrantLock的实现是一致的
Semaphore
Semaphore是信号量的概念,主要控制同一旉内对讉K资源的线E数的控制。底层实现是AQS?br />acquireShared()和releaseShared().

CountDownLatch
CountDownLatch在完成一l正在其他线E中执行的操作之前,允许U程{待直到他们完成操作
await()Ҏ一直等到state=0Q初始时CountDownLatch初始化stateZ入的数|一个线E?br />执行操作完成的话执行countDown()Ҏstate?Q直Cؓ0Qawait()Ҏ不再d?br />
CyclicBarrier
当一l线E调用CyclicBarrier.await()ҎQ就会阻塞在那里Q当最后一个线E进入调用此ҎӞ执?br />一个公qRunnable.原理是:初始化时有count属性,当前面count-1个线E到来都condition.await()Q第count?br />U程来就执行公共RunnableQ然后执行condition.signAll()Ҏ来得其他线E从d中解脱出?




nod0620 2011-09-18 00:12 发表评论
]]>
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阅读全文

nod0620 2011-09-15 22:57 发表评论
]]>
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.htmlU程状?/strong>
   jdk中线E状态分?new,runnable,blocked,waiting,timed_waiting,dead.其中new为刚创徏q没有开始执行的状态,
而runnable状态分为可以执行和正在执行Q可以执行是因ؓ可能要等cpu旉片等。blocked状态是指线E在d{待监视器的锁。waiting是指执行了Object.wait()QThread.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 setQ同旉要释攄视器的锁。监视器也是一个普通对象,在加上一些关键语法后Q就能成为监视器?br />当一个对象执行Object.notify()Ӟ是在waiting set选择一个threadq入ready setQ当q个thread能获得这个监视器的锁时候,可以进入runnable状态,否则待在ready setQnotifyAll()是通知waiting set里面的所有线E,然后选择其中的一个,不确定是哪一个,U程的优先也只是一个提C和指导?br />Object.wait(time)/Object.join(time)Ҏq些都是在时间限制到达之前thread在waiting setQ时间到期之后自动进入ready set?br />Thread.sleep()/Thread.yield()执行时thread都不会放弃监视器的锁Q只是进入ready setQThread.sleep()只是在指定的旉内休眠,得不CQ何的资源.Thread.yield()只是提示thread工作差不多完成了Q可以让步给其他ThreadQ这个让步不保证完成Q这个也只对同等U的U程有效?br />
监视?/strong>
   java使用监视器来表示同步锁,在Java里面QQ何一个Object Reference都可以作为同步锁Q只要用synchronizedQ?br />
public static final Object signal = new Object();
f1(){
   synchronized(signal){

   }
}
在jvm内部synchronized会被表示成monitorenter和monitorexit;在一个时间段Q只有一个线E能持有monitorQ也是在monitorenter里面Q也pC同步的目?当想获得一个类变量锁的时候,可以使用q个cȝclasscR?br />
内存模型
在jvm规范中规定java内存模型是java  thread  work  memory和java main  memory两部?br />每个thread一个thread  memoryQ初始ؓI,必要时和main memory通信


规范规定了工作内存和d存之间通信?个行为:use, assign, load, store,read,write, lock, and unlock
use:使用一个线E工作内存中的变量,看成U程的行?br />assign:讄一个线E工作内存中的变量,讄的值来自线E执行引擎,看成U程的行?br />readQ把d存的D到线E工作内存当中,看成d存的行ؓ
loadQ在read之后执行Q真正的把D到到工作内存当中Q看成线E的行ؓ
storeQ保存工作内存的|{下在执行write后传输给d存,看成U程的行?br />
writeQ在store后执行,看成d存的行ؓ
lock和unlock是获取监视器锁和释放锁的行ؓQ是W三方synchronized行ؓ


q样的内存模型就会有问题Q?br />U程工作内存是独立的Q在工作内存A的变量被工作内存B看到需要经qA-->d?->B的程度,那么什么时候进行工作内存到d存的通信呢?
q里需要涉及到~存一致性模型,卛_作内?~存)什么时候刷新和dd存必遵循一定的规则才可以?
java使用释放一致性模?在释N的时候写入主内存
也就是当synchronized表示的方法或者运行块执行l束时监视器锁释攑֐Q里面涉及的所有变?局部变量除?的值都写入了主内存Q当变量被其他线E看到的话,其值是最新的?br />那么Ҏ或运行块未进行同步,可能有两斚w的问?
1.Ҏ的执行顺序是未定?br />2.即Ҏ的执行顺序是相同的,׃工作内存的值未写到d存中也有可能有问?br />
thread在jvm当中执行的顺序和代码中看到的序可能是不一LQؓ了性能优化{代码可能进行重排序Q所有jmm定义?br />U程的执行顺序模型:happens-before模型Q规则如?
1.一个线E当中,先出现的指ohappens-before后出现的指o
2.构造器的里面指令happens-before创徏对象的指?br />3.对于一个监视器Qunlock  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我们可以认ؓ他符合了上面的第3?br />对于volatile变量Q保证了在线E每ơ修改后马上反映C内存当中Q也是可见性?/div>












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

nod0620 2011-09-14 16:53 发表评论
]]>linuxU录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
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 PIDQpkill process_nameQkillall comm 杀d部同名进E?br />15.symlinks 理和维护符号链?br />16.chkconfig 讄和检查系l的服务讄
17.查看所有的shell命oQ可以进行修?br />18.export 讄和显C环境变?br />19.find 查找文g命o
20.wcl计文g的行敎ͼ字数Q字节数Q文件名
21.grep 正则表达式搜?grep xxx 文gxxxQ?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


nod0620 2011-09-07 17:46 发表评论
]]>
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 ҎӞ必须一致地q回相同的整敎ͼ前提是将对象q行 equals 比较时所用的信息没有被修攏V?
  • 如果Ҏ equals(Object) ҎQ两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode Ҏ都必ȝ成相同的整数l果?
  • 如果Ҏ equals(Object) ҎQ两个对象不相等Q那么对q两个对象中的Q一对象上调?hashCode Ҏ不要求一定生成不同的整数l果?/li>
HashMap使用分离链接法,是在hashcode冲突的时候在hashcode对应的槽位用链表,查找的时候先hashcode扑ֈ槽位Q然后equals()Ҏ扑ֈ链表中对应的对象?br />jdk的容量是2^nơ,扑ֈ槽位使用位与的方式代替模的方式提高性能
装蝲因子是装载的对象和hash表L量的比|CؓλQ这个代表^均链表的长度Q在一ơ不成功要查扄q_节点?br />
λ,一ơ成功的查找则ؓ1+λ/2

分离链接法之外还有线性探法和^Ҏ法Q双散列{探法
探测法不是在冲突的时候利用链表进行存储,而是在冲H的位置往后查找一个空位置q行存储

U性探法会遇Cơ聚焦的问题Q就是一个冲H的位置后面q箋的位|都不ؓI?br />
那么可以q行qx探测法消除一ơ聚焦的问题Q虽然我们引q了二次聚焦的较媄响的问题Q流行的函数为f(i)=i^2?br />
q个时候hash表的定w必须为素敎ͼq样在表一半ؓI时Q才能L插入一个元?br />如果定w为非素数的时候,备选位|要很?br />
|上讨论hashmap的个Cؓ素数或?^nơ问题,是没有分清分链接法和探法Q只有在探测法的时候,素数才是最有效?/div>


nod0620 2011-09-07 15:11 发表评论
]]>目结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这个下文再_q里我们叫photo表,下面所说的囄是求购消息?br />考虑到求购消息比较多Q所以需要进行分表,假设?个表?strong>׃业务的需求是Q可以查看单张图片,可以看一个用L囄列表Q问题来了,我们按什么进行分表?
看下表结?


id是图片的idQ要查询单张囄的话Q需要能快速的定位到哪一张表Q而查询一个用L囄列表的话Q需要快速找到这个用h有的囄Q那么这个用L囄应该是放?br />一个表里面的,即通过user_id能\由到一张表Q从而从q张表里面取得这个用h有的囄?strong>通过上面分析Q如果选择user_id对表数量取模的gؓ选择存储的第几个表,
那么一个user_id所有的囄都在一张表里面了,q里对id有要求Qid对表数量取模的D和user_id对表数量取模的g??br />q样做的l果是,id的g是连l的Q有些许的浪费,如果user_id分布不均的话Q对于每个表的数据量也会分布不均

2.评论?br />对图片进行评论,对于单个囄来说有评论列表,对于单个用户来说Q他能看到所有对他图片进行评论的评论列表Q所以采用了两套表的ҎQ对于用photo_id分表?br />的comment表,以及针对user_id分表的comment_u?br />

3.好友关系?br />q个cM于微薄里面的x或者粉丝表,和评一Pq里需要两套表Q一个是x表,一个是_丝?br />

Feed?/h3>当一个hx另外一个h的时候,那么被关注的人发表的囄是能被另外一个h看到的,q和微博的feed是一L?br />q里有两U方式实玎ͼpush模式(推模?Qpull模式(拉模?。push模式Q当一个用户发表图片的时候,索这个用L
_丝表,为每个粉丝插入一条feed。pull模式Q当一个用户发表图片的时候,只是存一份数据,当一个用h看他的关注的用户的feed的时候,需要先索关注表Q然后检索每一个关注用h没有新发的feed?br />
push和pull模式各有利弊Q当使用push模式的时候,如果一个用?名h)的粉丝过多的话,那么每个_丝插入一条feed对存储的压力太大了(100000_丝话,插入100000)Q存储空间浪费也非常的严重?br />pull模式的话Q如果一个用户关注过多的时候,查询该用Lx列表也是有很大的代h?br />
目用的是pull模式Q注意到求购目的特D性,一般只是看最新的求购的消息,假设某个用户当前?000条新feedQ这个用户也不能完全的看完,所以认为只要取得最新的消息里面的若q条Q其余的消息的话可以在历史feed列表里面看到或者下一ơ看刎ͼq里有个timeline的概c当ơ取得最新消息后Q需要把q个旉点保存,下次查询的时候,从这个时间点q行查询?br />
目具体的做法:
1.查询用户的关注列?br />2.从cache中取出timeline
3.timeline为空的话Q直接取出旧的feed 30条,更新timelineQ其中最新的一条的创徏旉为timeline
4.timeline不ؓI的话,取得timeline之后的feedQ最大gؓ30条,查过30条,取得的是最旧的30条,更新timelineQ其中最新的一条的创徏旉为timeline?br />

W?步其实和微博的做法是不同的,假设?000条feedQ微博是一ơ性刷出来Q而这个是一ơ刷?0条,q里有个博弈在里面:
一ơ刷?0条,h的次数多了,查询多了Q但是一?000条的单次查询压力大了Q还有多h看了30条之后l刷新看的? 所以我们采取降低单ơ刷新的代hQ这样对服务器峰值的压力也就下来?br />

其它

q有很多优化的点没有说出来,比如路由表取模的时候,是用位与操作?18%16==18&15)
q有各个能用到cache的地方尽量用cacheQ对于读写的话,可以增加d队列.
对于扩展Q性能Q后l考虑的:
当单个用户关注数过一定数目,q个用户需要特别的对待Q比如用户关注单独的变成一张表Q减关注表的压?br />对用h跃度q行分析Q活跃用Lfeed使用pull和push模式相结合的模式
对于_丝数很多的用户Q可以单独成表,发的feed可以先pushl一部分用户Q让一部分用户先看到feed.








nod0620 2011-08-31 15:50 发表评论
]]>二叉查找树复习简?/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保持排序状态,需要拿到这个节点的左子树的最大节Ҏ者右子树的最节点,得到q个节点的数据代替要删除的节点,</p><p>然后删除q个左子树的最大节Ҏ者右子树的最节点,因ؓ左子树的最大节Ҏ有右节点(有右节点的话Q他׃是最大的?,同理Q右子树的最节?/p><p>没有左节点,所以要删除的这个节点只有一个或者没有孩子节点,只需要进?)或?)完成了?/p><p> </p><div><br /><h3>AVL?/h3></div><br /><p> </p><p>在插入节Ҏ通过旋{(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 />     * 插入一个元素到树里面,可能破坏了高度差Q需要找C个节点aQ该节点左子树和叛_树被破坏了,则需要对q个节点(q因子)<br />     * <br />     * 树进行^衡,有四U情?<br />     * <br />     * 1.a节点的左儿子的左子树插入<br />     * <br />     * 2.a节点的左儿子的右子树插入<br />     * <br />     * 3.a节点的右儿子的左子树插入<br />     * <br />     * 4.a节点的右儿子的右子树插入<br />     * <br />     * <br />     * 1.4两种情况需要进行一ơ旋?br />     * <br />     * 2.3两种情况需要进行两ơ旋?br />     *<br />     * 旋{的目的是Z使插入节点的树的高度降低1Q所以只要求旋{q因子为根的树可以了<br />    </span><span style="color: #008000;">*/</span><span style="color: #000000;"><br /></span></div><p><br /></p>在删除节点的时候:<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他的左子树高度和右子树高度如果相差2的话Q就需要旋转,而且旋{后,q因子的节点ؓ根的树的高度肯定?br />     * <br />     * 下降1Q这样^衡因子所在的树的高度下降1Q也有可能需要进行旋转调_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?树中每个节点的左子树和右子树的高度最多差1的二叉查找树<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 />     * 插入一个元素到树里面,可能破坏了高度差Q需要找C个节点aQ该节点左子树和叛_树被破坏了,则需要对q个节点(q因子)<br />     * <br />     * 树进行^衡,有四U情?<br />     * <br />     * 1.a节点的左儿子的左子树插入<br />     * <br />     * 2.a节点的左儿子的右子树插入<br />     * <br />     * 3.a节点的右儿子的左子树插入<br />     * <br />     * 4.a节点的右儿子的右子树插入<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;"> 因ؓ左子树插入了节点Q那么左子树比右子树?Ҏavl树的性质Q插入了节点<br />            </span><span style="color: #008000;">//</span><span style="color: #008000;"> 要么高度差ؓ1Q要么高度差?Q所以当相差?Ӟ需要进行树的调?/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比树左子树的元素q小的话Q就是在树的左子树的左边插入节点Q成为左子树的左子树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比树左子树的元素q大的话Q就是在树的左子树的双插入节点Q成为左子树的右子树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比树叛_树的元素q大的话Q就是在树的叛_树的双插入节点Q成为右子树的右子树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比树叛_树的元素q小的话Q就是在树的叛_树的左边插入节点Q成为右子树的左子树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;"> 树里面有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他的左子树高度和右子树高度如果相差2的话Q就需要旋转,而且旋{后,q因子的节点ؓ根的树的高度肯定?br />     * <br />     * 下降1Q这样^衡因子所在的树的高度下降1Q也有可能需要进行旋转调_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/启动cd载器
他的parent为null, 主要负责'sun.boot.class.path'pȝ属性指定的 ?-Xbootclasspath 选项指定的jar包装入工?
Bootstrap ClassLoader是jvm控制的,不是java语言层面~写的,默认加蝲jdk_home/jre/lib/下面的jar包和其他相关的东西,如jdk的核心包rt.jar是在这里被加蝲?br />
Extension ClassLoader/扩展cd载器
主要负责jdk_home/jre/lib/ext目录?'java.ext.dirs'pȝ属性指?的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工?他的parent?Bootstrap ClassLoader

System ClassLoader/pȝcd载器
主要负责java -classpath/-Djava.class.path所指的目录下的cMjar包装入工?一般我们会配置环境变量classpathQ这个就是蝲入classpath指定的\径下jar和class,
q_我们指定一?."P是指定从当前目录下开始搜索classc?parent?Extension ClassLoader.

User Custom ClassLoader/用户自定义类加蝲?java.lang.ClassLoader的子c?
在程序运行期? 通过java.lang.ClassLoader的子cd载class文g.


classloader要加载class先从底向上传递给父亲加蝲c,最层的classloader如果能够加蝲加载进来,不行的话Q就自上而下传递,只到一个classloader能进行类的加载,
如果没有一个classloader能加载的话,׃抛出ClassNotFoundException或者NoClassDefFoundError异常Q这个就是双亲委z模?br />
classloaderq种模式保证了不同的classloader之间cM会相互的影响Q那么也保证了好的类不会被恶意的cL破坏Q这个也是jvm沙箱模式安全的一个保?br />
在不同classloader的同名的cd例不能互相沟通,cd转换QinstanceofQ如果这样做Q则会抛出ClassCastException.所以抛出ClassCastException的原因不止和l承Q实现有关系Q?br />q和classloader有关p?

当运行时发现一个新class要loadӞ除代码已指定由哪classloader的实例load外,先由调用者的classloader所在的classloader tree去loadQ如果superc?interfacecd于这个树是新的也一起会被load。这是caller classloader的概?
双亲委派可以被打_全权负责也可被打_所以运行时军_cL自哪里,q是由classloader树和load class的代码是怎样而决定?br />

Thread Context ClassLoaderQ线E上下文classloaderQ是hold住了一ClassLoader的实例,q个holder在线E运行流E里可以到达隐式传递classloader。这个classloader是一个不会主动load的实例,是说在q个U程q行下遇到新c这个classloader不会d去loadQ只有自q昑ּ代码或你看不见的jar里用昑ּ代码用这?div>classloader loadClass()或Class.forName()Q才会生效。因此,caller classloader?thread context classloaderQ在执行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 发表评论
]]>
վ֩ģ壺 | տ| ԭ| | | | ֳ| | | ³ľ| ܱ| ɽ| ͬ| | | Դ| | Ȫ| | ˫| Դ| | | | | ̨| ĩ| ϳ| ֹ| | ׼| ϲ| ӳ| | Զ| ľ| | | Ʊ| Ϫ| ÷|