??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久国产视频91,成人免费在线观看,亚洲欧美日韩国产中文 http://www.aygfsteel.com/microlab4321/category/24780.html适时ȝ是一U很好的彌补Ҏ!zh-cnWed, 05 Sep 2007 17:20:48 GMTWed, 05 Sep 2007 17:20:48 GMT60(?java基础(?QJava同步机制 http://www.aygfsteel.com/microlab4321/articles/142954.html冬天的猪冬天的猪Wed, 05 Sep 2007 09:24:00 GMThttp://www.aygfsteel.com/microlab4321/articles/142954.htmlhttp://www.aygfsteel.com/microlab4321/comments/142954.htmlhttp://www.aygfsteel.com/microlab4321/articles/142954.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/142954.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/142954.html出处:http://www.aygfsteel.com/crazycy/archive/2006/10/14/75085.html
方式有四U:?/span> ThreadLocal ?/span> synchronized( ) ?/span> wait() ?/span> notify() ?/span> volatile

目的Q都是ؓ了解军_U程中的对同一变量的访问冲H?br />


ThreadLocal
    .
?/span> ThreadLocal 保证不同U程拥有不同实例Q相同线E一定拥有相同的实例Q即为每一个用该变量的线E提供一个该变量值的副本Q每一个线E都可以独立改变自己的副本,而不是与其它U程的副本冲H?/span>

. ㈡优势:提供了线E安全的׃n对象

. ㈢与其它同步机制的区别:同步机制是ؓ了同步多个线E对相同资源的ƈ发访问,是ؓ了多个线E之间进行通信Q?/span> ThreadLocal 是隔d个线E的数据׃nQ从Ҏ上就不在多个U程之间׃n资源Q这样当然不需要多个线E进行同步了?/span>

. ㈣用技巧:需要多个线E之间进行通信Q用同步机Ӟ如果需要隔d个线E之间的׃n冲突Q推荐?/span> ThreadLocal Q线E安全)

volatile
    .?/span>volatile 修饰的成员变量在每次被线E访问时Q都从共享内存中重读该成员变量的倹{而且Q当成员变量发生变化ӞU程变化值回写到׃n内存?br /> .㈡优势:q样在Q何时刻,两个不同的线EL看到某个成员变量的同一个倹{?/span>
. ㈢缘由:Java
语言规范中指出:Z获得最佳速度Q允许线E保存共享成员变量的U有拯Q而且只当U程q入或者离开同步代码块时才与׃n成员变量的原始值对比?br />          q样当多个线E同时与某个对象交互Ӟ必要注意到要让线E及时的得到׃n成员变量的变化?/span>
         ?/span> volatile 关键字就是提C?/span> VM Q对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互?/span>
. ㈣用技巧:在两个或者更多的U程讉K的成员变量上使用 volatile 。当要访问的变量已在 synchronized 代码块中Q或者ؓ帔RӞ不必使用?/span>
                
׃使用 volatile 屏蔽掉了 VM 中必要的代码优化Q所以在效率上比较低Q因此一定在必要时才使用此关键字?br />
阐释Q?br /> U程Z提高效率Q将某成员变?/span>(?/span>A)拯了一份(?/span>BQ,U程中对A的访问其实访问的?/span>B?/span>
只在某些动作时才q行A?/span>B的同步,因此存在A?/span>B不一致的情况?/span>volatile是用来避免q种情况的?/span>
volatile
告诉jvmQ?/span>它所修饰的变量不保留拯Q直接访问主内存中的Q也是上面说的A)

sleep()  vs wait() 
  sleep是线E类QThreadQ的ҎQ导致此U程暂停执行指定旉Q把执行Zl其他线E,但是监控状态依然保持,到时后会自动恢复?br />            调用sleep不会释放对象锁?br />   wait是ObjectcȝҎQ对此对象调用waitҎD本线E放弃对象锁Q进入等待此对象的等待锁定池Q只有针Ҏ对象发出notifyҎQ或notifyAllQ后本线E才
          q入对象锁定池准备获得对象锁q入q行状态?br />



===================2007-05-01引用如下内容===========

早在Java 1.2推出之时QJavaq_中就引入了一个新的支持:java.lang.ThreadLocalQ给我们在编写多U程E序时提供了一U新的选择。用这个工L可以很简z地~写Z的多线E程序,虽然ThreadLocal非常有用Q但是似乎现在了解它、用它的朋友还不多?

  ThreadLocal是什?/strong>

  ThreadLocal是什么呢Q其实ThreadLocalq是一个线E的本地实现版本Q它q不是一个ThreadQ而是thread local variableQ线E局部变量)。也许把它命名ؓThreadLocalVar更加合适。线E局部变量(ThreadLocalQ其实的功用非常单,是为每一个用该变量的线E都提供一个变量值的副本Q是每一个线E都可以独立地改变自q副本Q而不会和其它U程的副本冲H。从U程的角度看Q就好像每一个线E都完全拥有该变量。线E局部变量ƈ不是Java的新发明Q在其它的一些语a~译器实玎ͼ如IBM XL FORTRANQ中Q它在语a的层ơ提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支持,所以,在Java中编写线E局部变量的代码相对比较W拙Q这也许是线E局部变量没有在Java中得到很好的普及的一个原因吧?br />
  ThreadLocal的设?/strong>

  首先看看ThreadLocal的接口:

  Object get() ; // q回当前U程的线E局部变量副?protected Object initialValue(); // q回该线E局部变量的当前U程的初始值void set(Object value); // 讄当前U程的线E局部变量副本的?br />
  ThreadLocal?个方法,其中值得注意的是initialValue()Q该Ҏ是一个protected的方法,昄是ؓ了子c重写而特意实现的。该Ҏq回当前U程在该U程局部变量的初始|q个Ҏ是一个gq调用方法,在一个线E第1ơ调用get()或者set(Object)时才执行Qƈ且仅执行1ơ。ThreadLocal中的实实现直接q回一个nullQ?br />
protected Object initialValue() { return null; }

  ThreadLocal是如何做Cؓ每一个线E维护变量的副本的呢Q其实实现的思\很简单,在ThreadLocalcM有一个MapQ用于存储每一个线E的变量的副本。比如下面的CZ实现Q?br />
public class ThreadLocal
{
 private Map values = Collections.synchronizedMap(new HashMap());
 public Object get()
 {
  Thread curThread = Thread.currentThread();
  Object o = values.get(curThread);
  if (o == null && !values.containsKey(curThread))
  {
   o = initialValue();
   values.put(curThread, o);
  }
  return o;
 }

 public void set(Object newValue)
 {
  values.put(Thread.currentThread(), newValue);
 }

 public Object initialValue()
 {
  return null;
 }
}

  当然Q这q不是一个工业强度的实现Q但JDK中的ThreadLocal的实现M思\也类g此?br />
  ThreadLocal的?/strong>

  如果希望U程局部变量初始化其它|那么需要自己实现ThreadLocal的子cdƈ重写该方法,通常使用一个内部匿名类对ThreadLocalq行子类化,比如下面的例子,SerialNumcMؓ每一个类分配一个序P

public class SerialNum
{
 // The next serial number to be assigned

 private static int nextSerialNum = 0;
 private static ThreadLocal serialNum = new ThreadLocal()
 {
  protected synchronized Object initialValue()
  {
   return new Integer(nextSerialNum++);
  }
 };

 public static int get()
 {
  return ((Integer) (serialNum.get())).intValue();
 }
}

  SerialNumcȝ使用非常地单,因ؓget()Ҏ是static的,所以在需要获取当前线E的序号Ӟ单地调用Q?br />
int serial = SerialNum.get();

  卛_?br />
  在线E是zd的ƈ且ThreadLocal对象是可讉K的时Q该U程持有一个到该线E局部变量副本的隐含引用Q当该线E运行结束后Q该U程拥有的所以线E局部变量的副本都将失效Qƈ{待垃圾攉器收集?br />
  ThreadLocal与其它同步机制的比较

  ThreadLocal和其它同步机制相比有什么优势呢QThreadLocal和其它所有的同步机制都是Z解决多线E中的对同一变量的访问冲H,在普通的同步机制中,是通过对象加锁来实现多个线E对同一变量的安全访问的。这时该变量是多个线E共享的Q用这U同步机刉要很l致地分析在什么时候对变量q行dQ什么时候需要锁定某个对象,什么时候释放该对象的锁{等很多。所有这些都是因为多个线E共享了资源造成的。ThreadLocal׃另一个角度来解决多线E的q发讉KQThreadLocal会ؓ每一个线E维护一个和该线E绑定的变量的副本,从而隔M多个U程的数据,每一个线E都拥有自己的变量副本,从而也没有必要对该变量进行同步了。ThreadLocal提供了线E安全的׃n对象Q在~写多线E代码时Q可以把不安全的整个变量装qThreadLocalQ或者把该对象的特定于线E的状态封装进ThreadLocal?br />
  ׃ThreadLocal中可以持有Q何类型的对象Q所以用ThreadLocal get当前U程的值是需要进行强制类型{换。但随着新的Java版本Q?.5Q将模版的引入,新的支持模版参数的ThreadLocal<T>cd从中受益。也可以减少强制cd转换Qƈ一些错误检查提前到了编译期Q将一定程度地化ThreadLocal的用?br />
  ȝ

  当然ThreadLocalq不能替代同步机Ӟ两者面向的问题领域不同。同步机制是Z同步多个U程对相同资源的q发讉KQ是Z多个U程之间q行通信的有效方式;而ThreadLocal是隔d个线E的数据׃nQ从Ҏ上就不在多个U程之间׃n资源Q变量)Q这样当然不需要对多个U程q行同步了。所以,如果你需要进行多个线E之间进行通信Q则使用同步机制Q如果需要隔d个线E之间的׃n冲突Q可以用ThreadLocalQ这极大地化你的程序,使程序更加易诅R简z?br />


冬天的猪 2007-09-05 17:24 发表评论
]]>
摘JAVA基础(?Qfor循环 http://www.aygfsteel.com/microlab4321/articles/142696.html冬天的猪冬天的猪Tue, 04 Sep 2007 09:26:00 GMThttp://www.aygfsteel.com/microlab4321/articles/142696.htmlhttp://www.aygfsteel.com/microlab4321/comments/142696.htmlhttp://www.aygfsteel.com/microlab4321/articles/142696.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/142696.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/142696.htmlJAVA基础(?Qfor循环
forQexpr1; expr2; expr3Q的执行序Q?br /> ----初始化工作的expr1;    
----判断expr2是否为真

如果为真
-----执行for?br /> -----执行expr3
-----判断expr2是否为真
循环?br />
如果为假
-----不执行for?br /> -----不执行expr3

CZQ?br />
 1public   class   Delta    {   
 2      static   boolean   foo(char   c)  {   
 3          System.out.print(c);   
 4          return   true;   
 5      }
   
 6      public   static   void   main(String[]   argv) {   
 7          int   i   =   0;   
 8          for   (foo('A');   foo('B')   &&   (i   <   2);   foo('C')) {   
 9              i++;   
10              foo('D');   
11          }
   
12      }
   
13}
  

ABDCBDCB


冬天的猪 2007-09-04 17:26 发表评论
]]>
(?JAVA基础(一)Q多?overloading & overridding)的分?http://www.aygfsteel.com/microlab4321/articles/142683.html冬天的猪冬天的猪Tue, 04 Sep 2007 09:09:00 GMThttp://www.aygfsteel.com/microlab4321/articles/142683.htmlhttp://www.aygfsteel.com/microlab4321/comments/142683.htmlhttp://www.aygfsteel.com/microlab4321/articles/142683.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/142683.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/142683.html阅读全文

冬天的猪 2007-09-04 17:09 发表评论
]]>
关于java当中的多U程设计, wait/notify机制 , synchronized与对象锁 http://www.aygfsteel.com/microlab4321/articles/140068.html冬天的猪冬天的猪Mon, 27 Aug 2007 09:46:00 GMThttp://www.aygfsteel.com/microlab4321/articles/140068.htmlhttp://www.aygfsteel.com/microlab4321/comments/140068.htmlhttp://www.aygfsteel.com/microlab4321/articles/140068.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/140068.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/140068.htmlhttp://www.aygfsteel.com/site120/archive/2007/01/08/92484.html

java多线E设计wait/notify机制 (synchronized与对象锁)

作?--猥琐ing

多线E之间需要协调工作。例如,览器的一个显C图片的U程displayThread惌执行昄囄的Q务,必须{待下蝲U程downloadThread该囄下蝲完毕。如果图片还没有下蝲完,displayThread可以暂停Q当downloadThread完成了Q务后Q再通知displayThread“囄准备完毕Q可以显CZ”Q这ӞdisplayThreadl箋执行?

以上逻辑单的说就是:如果条g不满I则等待。当条g满Ӟ{待该条件的U程被唤醒。在Java中,q个机制的实C赖于wait/notify。等待机制与锁机制是密切兌的。例如:

synchronized(obj) {
    while(!condition) {
        obj.wait();
    }
    obj.doSomething();
}

当线EA获得了obj锁后Q发现条件condition不满I无法l箋下一处理Q于是线EAwait() , 攑ּ对象?

之后在另一U程B中,如果B更改了某些条Ӟ使得U程A的condition条g满了,可以唤醒线EAQ?/p>

synchronized(obj) {
    condition = true;
    obj.notify();
}

需要注意的概念是:

# 调用obj的wait(), notify()Ҏ前,必须获得obj锁,也就是必d在synchronized(obj) {...} 代码D内?/p>

# 调用obj.wait()后,U程A释放了obj的锁Q否则线EB无法获得obj锁,也就无法在synchronized(obj) {...} 代码D内唤醒A?/p>

# 当obj.wait()Ҏq回后,U程A需要再ơ获得obj锁,才能l箋执行?/p>

# 如果A1,A2,A3都在obj.wait()Q则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM军_Q?/p>

# obj.notifyAll()则能全部唤醒A1,A2,A3Q但是要l箋执行obj.wait()的下一条语句,必须获得obj锁,因此QA1,A2,A3只有一个有Z获得锁l执行,例如A1Q其余的需要等待A1释放obj锁之后才能l执行?/p>

# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此QA1,A2,A3虽被唤醒Q但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后QA1,A2,A3中的一个才有机会获得锁l箋执行?/p>

冬天的猪 2007-08-27 17:46 发表评论
]]>
用Java实现几种常见的排序算?http://www.aygfsteel.com/microlab4321/articles/138178.html冬天的猪冬天的猪Mon, 20 Aug 2007 08:19:00 GMThttp://www.aygfsteel.com/microlab4321/articles/138178.htmlhttp://www.aygfsteel.com/microlab4321/comments/138178.htmlhttp://www.aygfsteel.com/microlab4321/articles/138178.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/138178.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/138178.html插入排序Q?/p>

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;
/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class InsertSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                SortUtil.swap(data,j,j-1);
            }
        }       
    }

}

冒排序Q?/p>

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class BubbleSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for(int i=0;i<data.length;i++){
            for(int j=data.length-1;j>i;j--){
                if(data[j]<data[j-1]){
                    SortUtil.swap(data,j,j-1);
                }
            }
        }
    }

}

选择排序Q?/p>

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SelectionSort implements SortUtil.Sort {

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int temp;
        for (int i = 0; i < data.length; i++) {
            int lowIndex = i;
            for (int j = data.length - 1; j > i; j--) {
                if (data[j] < data[lowIndex]) {
                    lowIndex = j;
                }
            }
            SortUtil.swap(data,i,lowIndex);
        }
    }

}

Shell排序Q?/p>

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ShellSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        for(int i=data.length/2;i>2;i/=2){
            for(int j=0;j<i;j++){
                insertSort(data,j,i);
            }
        }
        insertSort(data,0,1);
    }

    /**
     * @param data
     * @param j
     * @param i
     */
    private void insertSort(int[] data, int start, int inc) {
        int temp;
        for(int i=start+inc;i<data.length;i+=inc){
            for(int j=i;(j>=inc)&&(data[j]<data[j-inc]);j-=inc){
                SortUtil.swap(data,j,j-inc);
            }
        }
    }

}

快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class QuickSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        quickSort(data,0,data.length-1);       
    }
    private void quickSort(int[] data,int i,int j){
        int pivotIndex=(i+j)/2;
        file://swap
        SortUtil.swap(data,pivotIndex,j);
        
        int k=partition(data,i-1,j,data[j]);
        SortUtil.swap(data,k,j);
        if((k-i)>1) quickSort(data,i,k-1);
        if((j-k)>1) quickSort(data,k+1,j);
        
    }
    /**
     * @param data
     * @param i
     * @param j
     * @return
     */
    private int partition(int[] data, int l, int r,int pivot) {
        do{
           while(data[++l]<pivot);
           while((r!=0)&&data[--r]>pivot);
           SortUtil.swap(data,l,r);
        }
        while(l<r);
        SortUtil.swap(data,l,r);       
        return l;
    }

}

改进后的快速排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedQuickSort implements SortUtil.Sort {

    private static int MAX_STACK_SIZE=4096;
    private static int THRESHOLD=10;
    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] stack=new int[MAX_STACK_SIZE];
        
        int top=-1;
        int pivot;
        int pivotIndex,l,r;
       
        stack[++top]=0;
        stack[++top]=data.length-1;
       
        while(top>0){
            int j=stack[top--];
            int i=stack[top--];
           
            pivotIndex=(i+j)/2;
            pivot=data[pivotIndex];
           
            SortUtil.swap(data,pivotIndex,j);
           
            file://partition
            l=i-1;
            r=j;
            do{
                while(data[++l]<pivot);
                while((r!=0)&&(data[--r]>pivot));
                SortUtil.swap(data,l,r);
            }
            while(l<r);
            SortUtil.swap(data,l,r);
            SortUtil.swap(data,l,j);
           
            if((l-i)>THRESHOLD){
                stack[++top]=i;
                stack[++top]=l-1;
            }
            if((j-l)>THRESHOLD){
                stack[++top]=l+1;
                stack[++top]=j;
            }
           
        }
        file://new InsertSort().sort(data);
        insertSort(data);
    }
    /**
     * @param data
     */
    private void insertSort(int[] data) {
        int temp;
        for(int i=1;i<data.length;i++){
            for(int j=i;(j>0)&&(data[j]<data[j-1]);j--){
                SortUtil.swap(data,j,j-1);
            }
        }      
    }

}

归ƈ排序Q?/p>

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class MergeSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }
    
    private void mergeSort(int[] data,int[] temp,int l,int r){
        int mid=(l+r)/2;
        if(l==r) return ;
        mergeSort(data,temp,l,mid);
        mergeSort(data,temp,mid+1,r);
        for(int i=l;i<=r;i++){
            temp[i]=data[i];
        }
        int i1=l;
        int i2=mid+1;
        for(int cur=l;cur<=r;cur++){
            if(i1==mid+1)
                data[cur]=temp[i2++];
            else if(i2>r)
                data[cur]=temp[i1++];
            else if(temp[i1]<temp[i2])
                data[cur]=temp[i1++];
            else
                data[cur]=temp[i2++];           
        }
    }

}

改进后的归ƈ排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class ImprovedMergeSort implements SortUtil.Sort {

    private static final int THRESHOLD = 10;

    /*
     * (non-Javadoc)
     *
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        int[] temp=new int[data.length];
        mergeSort(data,temp,0,data.length-1);
    }

    private void mergeSort(int[] data, int[] temp, int l, int r) {
        int i, j, k;
        int mid = (l + r) / 2;
        if (l == r)
            return;
        if ((mid - l) >= THRESHOLD)
            mergeSort(data, temp, l, mid);
        else
            insertSort(data, l, mid - l + 1);
        if ((r - mid) > THRESHOLD)
            mergeSort(data, temp, mid + 1, r);
        else
            insertSort(data, mid + 1, r - mid);

        for (i = l; i <= mid; i++) {
            temp[i] = data[i];
        }
        for (j = 1; j <= r - mid; j++) {
            temp[r - j + 1] = data[j + mid];
        }
        int a = temp[l];
        int b = temp[r];
        for (i = l, j = r, k = l; k <= r; k++) {
            if (a < b) {
                data[k] = temp[i++];
                a = temp[i];
            } else {
                data[k] = temp[j--];
                b = temp[j];
            }
        }
    }

    /**
     * @param data
     * @param l
     * @param i
     */
    private void insertSort(int[] data, int start, int len) {
        for(int i=start+1;i<start+len;i++){
            for(int j=i;(j>start) && data[j]<data[j-1];j--){
                SortUtil.swap(data,j,j-1);
            }
        }
    }
}

堆排序:

package org.rut.util.algorithm.support;

import org.rut.util.algorithm.SortUtil;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class HeapSort implements SortUtil.Sort{

    /* (non-Javadoc)
     * @see org.rut.util.algorithm.SortUtil.Sort#sort(int[])
     */
    public void sort(int[] data) {
        MaxHeap h=new MaxHeap();
        h.init(data);
        for(int i=0;i<data.length;i++)
            h.remove();
        System.arraycopy(h.queue,1,data,0,data.length);
    }

     private static class MaxHeap{         
        
        void init(int[] data){
            this.queue=new int[data.length+1];
            for(int i=0;i<data.length;i++){
                queue[++size]=data[i];
                fixUp(size);
            }
        }
        
        private int size=0;

        private int[] queue;
                
        public int get() {
            return queue[1];
        }

        public void remove() {
            SortUtil.swap(queue,1,size--);
            fixDown(1);
        }
        file://fixdown
        private void fixDown(int k) {
            int j;
            while ((j = k << 1) <= size) {
                if (j < size && queue[j]<queue[j+1])
                    j++;
                if (queue[k]>queue[j]) file://?/font>用交?br>                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }
        private void fixUp(int k) {
            while (k > 1) {
                int j = k >> 1;
                if (queue[j]>queue[k])
                    break;
                SortUtil.swap(queue,j,k);
                k = j;
            }
        }

    }

}

SortUtilQ?/p>

package org.rut.util.algorithm;

import org.rut.util.algorithm.support.BubbleSort;
import org.rut.util.algorithm.support.HeapSort;
import org.rut.util.algorithm.support.ImprovedMergeSort;
import org.rut.util.algorithm.support.ImprovedQuickSort;
import org.rut.util.algorithm.support.InsertSort;
import org.rut.util.algorithm.support.MergeSort;
import org.rut.util.algorithm.support.QuickSort;
import org.rut.util.algorithm.support.SelectionSort;
import org.rut.util.algorithm.support.ShellSort;

/**
 * @author treeroot
 * @since 2006-2-2
 * @version 1.0
 */
public class SortUtil {
    public final static int INSERT = 1;
    public final static int BUBBLE = 2;
    public final static int SELECTION = 3;
    public final static int SHELL = 4;
    public final static int QUICK = 5;
    public final static int IMPROVED_QUICK = 6;
    public final static int MERGE = 7;
    public final static int IMPROVED_MERGE = 8;
    public final static int HEAP = 9;

    public static void sort(int[] data) {
        sort(data, IMPROVED_QUICK);
    }
    private static String[] name={
            "insert", "bubble", "selection", "shell", "quick", "improved_quick", "merge", "improved_merge", "heap"
    };
    
    private static Sort[] impl=new Sort[]{
            new InsertSort(),
            new BubbleSort(),
            new SelectionSort(),
            new ShellSort(),
            new QuickSort(),
            new ImprovedQuickSort(),
            new MergeSort(),
            new ImprovedMergeSort(),
            new HeapSort()
    };

    public static String toString(int algorithm){
        return name[algorithm-1];
    }
    
    public static void sort(int[] data, int algorithm) {
        impl[algorithm-1].sort(data);
    }

    public static interface Sort {
        public void sort(int[] data);
    }

    public static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
}



冬天的猪 2007-08-20 16:19 发表评论
]]>
String ?StringBuffer 的效率比?http://www.aygfsteel.com/microlab4321/articles/137290.html冬天的猪冬天的猪Thu, 16 Aug 2007 07:43:00 GMThttp://www.aygfsteel.com/microlab4321/articles/137290.htmlhttp://www.aygfsteel.com/microlab4321/comments/137290.htmlhttp://www.aygfsteel.com/microlab4321/articles/137290.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/137290.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/137290.html?6个英文字母重复加?000ơ,

String tempstr = "abcdefghijklmnopqrstuvwxyz";
int times = 5000;
long lstart1=System.currentTimeMillis();
  String str ="";
  for(int i=0;i<times;i++)
  {
   str+=tempstr;
  }
  
  long lend1=System.currentTimeMillis();
  long time = (lend1-lstart1);
  System.out.println(time);

可惜我的计算Z是超U计机Q得到的l果每次不一定一样一般ؓ 154735 左右?br>也就?54U?br>我们再看看以下代?br>
String tempstr = "abcdefghijklmnopqrstuvwxyz";
 
  int times = 5000;
long lstart2=System.currentTimeMillis();
  StringBuffer sb =new  StringBuffer();
  for(int i=0;i<times;i++)
  {
   sb.append(tempstr);
   
  }
  long lend2=System.currentTimeMillis();
  long time2 = (lend2-lstart2);
  System.out.println(time2);
 得到的结果ؓ 16 有时q是 0
所以结论很明显QStringBuffer 的速度几乎是String 上万倍。当然这个数据不是很准确。因为@环的ơ数?00000ơ的时候,差异更大。不信你试试?br>下一ơ我解释ؓ什么StringBuffer 的效率比String 高这么多?

冬天的猪 2007-08-16 15:43 发表评论
]]>
java.util.Calendar中的陷阱 http://www.aygfsteel.com/microlab4321/articles/137267.html冬天的猪冬天的猪Thu, 16 Aug 2007 06:54:00 GMThttp://www.aygfsteel.com/microlab4321/articles/137267.htmlhttp://www.aygfsteel.com/microlab4321/comments/137267.htmlhttp://www.aygfsteel.com/microlab4321/articles/137267.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/137267.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/137267.html需求:
从输入框得到用户分开输入的年、月、日Q将信息做ؓDatecd插入数据?/p>

解决一Q?/p>

InputBean bean = new InputBean(); // 装用户输入

// 获取用户输入Q封装于bean对象?/span>

Calendar cal 
= Calendar.getInstance();
cal.set(cal.YEAR,bean.getYear()); 
// Year
cal.set(cal.MONTH,bean.getMonth()); // Month
cal.set(cal.DAY_OF_MONTH,bean.getDay()); // Day

// 数据库操?/span>

陷阱Q?br>Calendar中的MONTH字段和数l下标一P?开始,0代表Calendar.JANUARYQ?代表Calendar.FEBUARY……12代表ơ年Calendar.JANUARY。因此用戯入的月䆾在置入Calendar对象之前必须q行处理Q即减一?br>
解决二:

InputBean bean = new InputBean(); // 装用户输入

// 获取用户输入Q封装于bean对象?/span>

Calendar cal 
= Calendar.getInstance();
cal.set(cal.YEAR,bean.getYear()); 
// Year
cal.set(cal.MONTH,bean.getMonth() - 1); // Month
cal.set(cal.DAY_OF_MONTH,bean.getDay()); // Day


冬天的猪 2007-08-16 14:54 发表评论
]]>
接口与Objectcȝ关系Q?http://www.aygfsteel.com/microlab4321/articles/137265.html冬天的猪冬天的猪Thu, 16 Aug 2007 06:50:00 GMThttp://www.aygfsteel.com/microlab4321/articles/137265.htmlhttp://www.aygfsteel.com/microlab4321/comments/137265.htmlhttp://www.aygfsteel.com/microlab4321/articles/137265.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/137265.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/137265.html
1Map map = new HashMap();
2map.clone();

Map是一个接口,HashMap是一个类。clone()Ҏ在ObjectcM定义Q因此我下意识认为第二行可以q么写。结果编译器报错Qclone()Ҏ未定义。这个错误让我很郁闷Q看了半天doc才发原来Map是一个接口,而接口和ObjectcL有Q何关p,所以Map也就没有l承clone()。于是把代码Ҏ下面的样子:

1HashMap map = new HashMap();
2map.clone();

q样可以了?

兄弟Q你q样是测试不出来的。java是绝对多态的?
Map map = new HashMap();
map.clone()调用相当于HashMap.clone()也就是说调用的是从HashMap中的cloneҎ。但是你没有看清楚object的文档,class要显式implements Clonable接口才可以调用cloneҎ?nbsp;

冬天的猪 2007-08-16 14:50 发表评论
]]>
Java容器分析--数组http://www.aygfsteel.com/microlab4321/articles/137050.html冬天的猪冬天的猪Wed, 15 Aug 2007 13:22:00 GMThttp://www.aygfsteel.com/microlab4321/articles/137050.htmlhttp://www.aygfsteel.com/microlab4321/comments/137050.htmlhttp://www.aygfsteel.com/microlab4321/articles/137050.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/137050.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/137050.html作者:Flyingis

    数组?/span>Java语言内置的类型,除此之外Q?/span>Java有多U保存对象引用的方式?/span>Javacd提供了一套相当完整的容器c,使用q些cȝҎ可以保存和操U对象。下面分别进行讨论,在研IJava容器cM前,先了解一下Java数组的基本功能和Ҏ?/span>

1.  数组的基本特?/span>

         数组与其它种cȝ容器(List/Set/Map)之间的区别在于效率、确定的cd和保存基本类型数据的能力。数l是一U高效的存储和随问对象引用序列的方式Q用数l可以快速的讉K数组中的元素。但是当创徏一个数l对?/span>(注意和对象数l的区别)后,数组的大也固定了Q当数组I间不的时候就再创Z个新的数l,把旧的数l中所有的引用复制到新的数l中?/span>

         Java中的数组和容器都需要进行边界检查,如果界׃得到一?/span>RuntimeException异常。这点和C++中有所不同Q?/span>C++?/span>vector的操作符[]不会做边界检查,q在速度上会有一定的提高Q?/span>Java的数l和容器会因为时d在的边界查带来一些性能上的开销?/span>

         Java中通用的容器类不会以具体的cd来处理对象,容器中的对象都是?/span>Objectcd处理的,q是Java中所有类的基cR另外,数组可以保存基本cdQ而容器不能,它只能保存Q意的Java对象?/span>

         一般情况下Q考虑到效率与cd查,应该可能考虑使用数组。如果要解决一般化的问题,数组可能会受C些限Ӟq时可以使用Java提供的容器类?/span> 

2.  操作数组的实用功?/span>

         ?/span>java.util.ArrayscMQ有许多static静态方法,提供了操作数l的一些基本功能:

         equals()Ҏ----用于比较两个数组是否相等Q相{的条g是两个数l的元素个数必须相等Qƈ且对应位|的元素也相{?/span>

         fill()Ҏ----用以某个值填充整个数l,q个Ҏ有点W?/span>

         asList()Ҏ----接受L的数lؓ参数Q将其{变ؓList容器?/span>

         binarySearch()Ҏ----用于在已l排序的数组中查扑օ素,需要注意的是必L已经排序q的数组。当Arrays.binarySearch()扑ֈ了查扄标时Q该Ҏ返回一个等于或大于0的|否则返回一个负|表示在该数组目前的排序状态下此目标元素所应该插入的位|。负值的计算公式?/span>“-x-1”?/span>x指的是第一个大于查扑֯象的元素在数l中的位|,如果数组中所有的元素都小于要查找的对象,?/span>x = a.size()。如果数l中包含重复的元素,则无法保证找到的是哪一个元素,如果需要对没有重复元素的数l排序,可以使用TreeSet或?/span>LinkedHashSet。另外,如果使用Comparator排序了某个对象数l,在用该Ҏ时必L供同LComparatorcd的参数。需要注意的是,基本cd数组无法使用Comparatorq行排序?/span>

         sort()Ҏ----Ҏl进行升序排序?/span>

         ?/span>Java标准cd中,另有staticҎSystem.arraycopy()用来复制数组Q它针对所有类型做了重载?/span>

 

3.  数组的排?/span>

         ?/span>Java1.0?/span>1.1两个版本中,cd~少基本的算法操作,包括排序的操作,Java2Ҏq行了改善。在q行排序的操作时Q需要根据对象的实际cd执行比较操作Q如果ؓ每种不同的类型各自编写一个不同的排序ҎQ将会得代码很难被复用。一般的E序设计目标应是“保持不变的事物与会发改变的事物相分?#8221;。在q里Q不变的是通用的排序算法,变化的是各种对象怺比较的方式?/span>

Java有两U方式来实现比较的功能,一U是实现java.lang.Comparable接口Q该接口只有一?/span>compareTo()ҎQƈ以一?/span>ObjectcMؓ参数Q如果当前对象小于参数则q回负|如果相等q回Ӟ如果当前对象大于参数则返回正倹{另一U比较方法是采用{略(strategy)设计模式Q将会发生变化的代码装在它自己的类({略对象)中,再将{略对象交给保持不变的代码中Q后者用此{略实现它的法。因此,可以Z同的比较方式生成不同的对象,它们用在同L排序E序中。在此情况下Q通过定义一个实CComparator接口的类而创Z一个策略,q个{略cLcompare()?/span>equals()两个ҎQ一般情况下实现compare()Ҏ卛_?/span>

使用上述两种Ҏ卛_对Q意基本类型的数组q行排序Q也可以对Q意的对象数组q行排序。再提示一遍,基本cd数组无法使用Comparatorq行排序?/span>

Java标准cd中的排序法针对排序的类型进行了优化——针对基本类型设计了“快速排?#8221;Q针对对象设计的“E_归ƈ排序”。一般不用担心其性能?br>



冬天的猪 2007-08-15 21:22 发表评论
]]>
Swt/Jface tableViewer入门教程一(昄tableViewer) http://www.aygfsteel.com/microlab4321/articles/136356.html冬天的猪冬天的猪Mon, 13 Aug 2007 05:28:00 GMThttp://www.aygfsteel.com/microlab4321/articles/136356.htmlhttp://www.aygfsteel.com/microlab4321/comments/136356.htmlhttp://www.aygfsteel.com/microlab4321/articles/136356.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/136356.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/136356.html阅读全文

冬天的猪 2007-08-13 13:28 发表评论
]]>
swt入门 --常用lg的?/title><link>http://www.aygfsteel.com/microlab4321/articles/136355.html</link><dc:creator>冬天的猪</dc:creator><author>冬天的猪</author><pubDate>Mon, 13 Aug 2007 05:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/microlab4321/articles/136355.html</guid><wfw:comment>http://www.aygfsteel.com/microlab4321/comments/136355.html</wfw:comment><comments>http://www.aygfsteel.com/microlab4321/articles/136355.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/microlab4321/comments/commentRss/136355.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/microlab4321/services/trackbacks/136355.html</trackback:ping><description><![CDATA[     摘要: swt的常用组件button ,text ,combo,list ,q有一些容器类composite ,groupQ这里选择几个Q列写简单的用法不写解释了,因ؓ代码很简单,而且代码上的注释以说明.1,combo  和text package com.test;import org.eclipse.swt.SWT;import org.eclipse.sw...  <a href='http://www.aygfsteel.com/microlab4321/articles/136355.html'>阅读全文</a><img src ="http://www.aygfsteel.com/microlab4321/aggbug/136355.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/microlab4321/" target="_blank">冬天的猪</a> 2007-08-13 13:27 <a href="http://www.aygfsteel.com/microlab4321/articles/136355.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>面试常见问题1: 字符串分?http://www.aygfsteel.com/microlab4321/articles/136353.html冬天的猪冬天的猪Mon, 13 Aug 2007 05:23:00 GMThttp://www.aygfsteel.com/microlab4321/articles/136353.htmlhttp://www.aygfsteel.com/microlab4321/comments/136353.htmlhttp://www.aygfsteel.com/microlab4321/articles/136353.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/136353.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/136353.html下午面试两个同志, 感觉现在的同志们?Spring, Hibernate 很熟? 但是 J2SE 反而陌生了.

可以用两个方法来分割字符串ؓ数组.

1. java.lang.String ?split() Ҏ, JDK 1.4 or later

 

split
public String[] split(String regex,
int limit)
Ҏ匚wl定?a >正则表达?/font>来拆分此字符丌Ӏ?

此方法返回的数组包含此字W串的每个子字符Ԍq些子字W串由另一个匹配给定的表达式的子字W串l止或由字符串结束来l止。数l中的子字符串按它们在此字符串中的顺序排列。如果表辑ּ不匹配输入的M部分Q则l果数组只具有一个元素,x字符丌Ӏ?

limit 参数控制模式应用的次敎ͼ因此影响l果数组的长度。如果该限制 n 大于 0Q则模式被最多应?n - 1 ơ,数组的长度将不会大于 nQ而且数组的最后项包含超出最后匹配的定界W的所有输入。如?n 为非正,则模式将被应用尽可能多的ơ数Q而且数组可以是Q意长度。如?n 为零Q则模式被应用可能多的次敎ͼ数组可有M长度Qƈ且结字符串将被丢弃?

例如Q字W串 "boo:and:foo" 使用q些参数可生成下列结果:

Regex
Limit
l果

:
2
{ "boo", "and:foo" }

:
5
{ "boo", "and", "foo" }

:
-2
{ "boo", "and", "foo" }

o
5
{ "b", "", ":and:f", "", "" }

o
-2
{ "b", "", ":and:f", "", "" }

o
0
{ "b", "", ":and:f" }

q种形式的方法调?str.split(regex, n) 产生与以下表辑ּ完全相同的结果:

Pattern.compile(regex).split(str, n)
参数Q?/strong>
regex - 定界正则表达?
limit - l果阈|如上所q?
q回Q?/strong>
字符串数l,Ҏl定正则表达式的匚w来拆分此字符Ԍ从而生成此数组
抛出Q?/strong>
PatternSyntaxException - 如果正则表达式的语法无效
从以下版本开始:
1.4
另请参见Q?/strong>
Pattern

split
public String[] split(String regex)
Ҏl定的正则表辑ּ的匹配来拆分此字W串?

该方法的作用像是用给定的表达式和限制参数 0 来调用两参数 split Ҏ。因此,l果数组中不包括l尾I字W串?

例如Q字W串 "boo:and:foo" 产生带有下面q些表达式的l果Q?

Regex
l果

:
{ "boo", "and", "foo" }

o
{ "b", "", ":and:f" }

参数Q?/strong>
regex - 定界正则表达?
q回Q?/strong>
字符串数l,Ҏl定正则表达式的匚w来拆分此字符Ԍ从而生成此数组?
抛出Q?/strong>
PatternSyntaxException - 如果正则表达式的语法无效
从以下版本开始:
1.4
另请参见Q?/strong>
Pattern

2. java.util.Tokenizer JDK 1.0 or later

 

 

string tokenizer cd许应用程序将字符串分解ؓ标记。tokenization Ҏ?StreamTokenizer cL使用的方法更单?code>StringTokenizer Ҏ不区分标识符、数和带引号的字W串Q它们也不识别ƈ跌注释?

可以在创建时指定Q也可以Ҏ每个标记来指定分隔符Q分隔标记的字符Q集合?

StringTokenizer 的实例有两种行ؓ方式Q这取决于它在创建时使用?returnDelims 标志的值是 true q是 falseQ?

  • 如果标志?falseQ则分隔W字W用来分隔标记。标记是q箋字符Q不是分隔符Q的最大序列?
  • 如果标志?trueQ则认ؓ那些分隔W字W本w即为标记。因此标记要么是一个分隔符字符Q要么是那些q箋字符Q不是分隔符Q的最大序列?

StringTokenizer 对象在内部维护字W串中要被标记的当前位置。某些操作将此当前位|移臛_处理的字W后?

通过截取字符串的一个子串来q回标记Q该字符串用于创?StringTokenizer 对象?

下面是一个?tokenizer 的实例。代码如下:

     StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}

输出以下字符Ԍ

     this
is
a
test
StringTokenizer 是出于兼Ҏ的原因而被保留的遗留类Q虽然在C码中q不鼓励使用它)。徏议所有寻求此功能的h使用 String ?split Ҏ?java.util.regex 包?

下面的示例阐明了如何使用 String.split Ҏ字W串分解为基本标讎ͼ

     String[] result = "this is a test".split("\\s");
for (int x=0; x<result.length; x++)
System.out.println(result[x]);

输出以下字符Ԍ

     this
is
a
test


冬天的猪 2007-08-13 13:23 发表评论
]]>
Swt/Jfaceq度?http://www.aygfsteel.com/microlab4321/articles/136309.html冬天的猪冬天的猪Mon, 13 Aug 2007 02:30:00 GMThttp://www.aygfsteel.com/microlab4321/articles/136309.htmlhttp://www.aygfsteel.com/microlab4321/comments/136309.htmlhttp://www.aygfsteel.com/microlab4321/articles/136309.html#Feedback0http://www.aygfsteel.com/microlab4321/comments/commentRss/136309.htmlhttp://www.aygfsteel.com/microlab4321/services/trackbacks/136309.html1Q普通的q度?br>
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


public class TestProgress {
    
static boolean stopflg = false;
    
/**
     * Launch the application
     * 
@param args
     
*/

    
public static void main(String[] args) throws Exception{
        
final Display display = Display.getDefault();
        
final Shell shell = new Shell();
        shell.setSize(
500375);
        shell.setText(
"SWT Application");
        
        
//
        IRunnableWithProgress runnable = new IRunnableWithProgress(){
            
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                monitor.beginTask(
"generate"30);
                
for(int i=0;i<100;i++){
                    
if(monitor.isCanceled()){
                        
return;
                    }

                    monitor.worked(
1);
                    Thread.sleep(
50);
                }

                
                monitor.done();
            }

        }
;
        
new ProgressMonitorDialog(shell).run(truetrue, runnable);
        shell.open();
        shell.layout();
        
while (!shell.isDisposed()) {
            
if (!display.readAndDispatch())
                display.sleep();
        }

    }


}

2,反复循环的进度条
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


public class TestProgress {
    
static boolean stopflg = false;
    
/**
     * Launch the application
     * 
@param args
     
*/

    
public static void main(String[] args) throws Exception{
        
final Display display = Display.getDefault();
        
final Shell shell = new Shell();
        shell.setSize(
500375);
        shell.setText(
"SWT Application");
        
        
//
        IRunnableWithProgress runnable = new IRunnableWithProgress(){
            
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                monitor.beginTask(
"generate"30);
                
int i=0;
                
while(true){
                    
if(stopflg){
                        
break;
                    }

                    i
++;
                    
if(i==30){
                        i
=0;
                        monitor.beginTask(
"generate"30);
                    }

                    monitor.worked(
1);
                    Thread.sleep(
100);
                }

                monitor.done();
            }

        }
;
        
new ProgressMonitorDialog(shell).run(truetrue, runnable);
        shell.open();
        shell.layout();
        
while (!shell.isDisposed()) {
            
if (!display.readAndDispatch())
                display.sleep();
        }

    }


}

3,rcp中后CQ务的q度?br>使用Job建立后台dQ只需要设|job.setUser(true)q度条就出现了,和上边一Pq度条需要自己来控制q度。如果做一个cool的进度条Q就看你如何让进度条昄出实际的dq程?

冬天的猪 2007-08-13 10:30 发表评论
]]>
վ֩ģ壺 żҿ| ͨ| Ͻ| | | | Ӫ| | | ȫ| â| ΢| | ͭ| | ˮ| | | | | »| | ƽ| ʯ| | Դ| ר| ɽʡ| | Ʊ| ʤ| Т| | | Ӽ| | | ʼ| | ƽ| |