看源码,解疑惑

 看JDK源码,解疑惑

 

    从SUN公司主页上搞下来JDK5.0的源码,可以好好研究了。开始吧。

 

    1、Java定时器原理是怎么样的?

    解包jdk_sec-1_5_0-src-jrl,在/j2se/src/share/classes/java/util中找到Timer类。

  1. private TaskQueue queue = new TaskQueue();
  2. private TimerThread thread = new TimerThread(queue);

    我们找到了一个Timer的任务队列,找到了一个实际运行的线程类。

    再来看看还有什么:

  1.     private void mainLoop() {
  2.         while (true) {
  3.             try {
  4.                 TimerTask task;
  5.                 boolean taskFired;
  6.                 synchronized(queue) {
  7.                     // Wait for queue to become non-empty
  8.                     while (queue.isEmpty() && newTasksMayBeScheduled)
  9.                         queue.wait();
  10.                     if (queue.isEmpty())
  11.                         break// Queue is empty and will forever remain; die
  12.                     // Queue nonempty; look at first evt and do the right thing
  13.                     long currentTime, executionTime;
  14.                     task = queue.getMin();
  15.                     synchronized(task.lock) {
  16.                         if (task.state == TimerTask.CANCELLED) {
  17.                             queue.removeMin();
  18.                             continue;  // No action required, poll queue again
  19.                         }
  20.                         currentTime = System.currentTimeMillis();
  21.                         executionTime = task.nextExecutionTime;
  22.                         if (taskFired = (executionTime<=currentTime)) {
  23.                             if (task.period == 0) { // Non-repeating, remove
  24.                                 queue.removeMin();
  25.                                 task.state = TimerTask.EXECUTED;
  26.                             } else { // Repeating task, reschedule
  27.                                 queue.rescheduleMin(
  28.                                   task.period<0 ? currentTime   - task.period
  29.                                                 : executionTime + task.period);
  30.                             }
  31.                         }
  32.                     }
  33.                     if (!taskFired) // Task hasn't yet fired; wait
  34.                         queue.wait(executionTime - currentTime);
  35.                 }
  36.                 if (taskFired)  // Task fired; run it, holding no locks
  37.                     task.run();
  38.             } catch(InterruptedException e) {
  39.             }
  40.         }
  41.     }

    这是最核心的死循环方法,可以看见,在循环中通过不断地获取系统时间,直到特定时间到达。

 

-------------------------------------------------------我是无聊的分割线-------------------------------------------------------------------

 

    2、String类型实际是怎么实现的。

  1.     /** The value is used for character storage. */
  2.     private final char value[];
  3.     /** The offset is the first index of the storage that is used. */
  4.     private final int offset;
  5.     /** The count is the number of characters in the String. */
  6.     private final int count;
  7.     /** Cache the hash code for the string */
  8.     private int hash; // Default to 0

    看到了一个char类型数组,它才是实现String的根本,还有几个辅助属性。值得注意的是,String内容实际是不可变的,举例:

  1.     public String concat(String str) {
  2.     int otherLen = str.length();
  3.     if (otherLen == 0) {
  4.         return this;
  5.     }
  6.     char buf[] = new char[count + otherLen];
  7.     getChars(0, count, buf, 0);
  8.     str.getChars(0, otherLen, buf, count);
  9.     return new String(0, count + otherLen, buf);
  10.     }

    这是其中的一个字符串连接的方法,可以看到String所有的方法,只要是牵涉到对字符串更改的,一律调用构造器生成一个新的返回,而根本不更改本身的内容,不过StringBuffer的内容却是可变的,看源码便知。

 

-------------------------------------------------------我是可爱的分割线-------------------------------------------------------------------

 

    3、关于Thread。

    我们都知道Thread实现了Runnable接口。不过现在我们看看里面的一个有趣的方法:

  1.     public static void sleep(long millis, int nanos) 
  2.     throws InterruptedException {
  3.     if (millis < 0) {
  4.             throw new IllegalArgumentException("timeout value is negative");
  5.     }
  6.     if (nanos < 0 || nanos > 999999) {
  7.             throw new IllegalArgumentException(
  8.                 "nanosecond timeout value out of range");
  9.     }
  10.     if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
  11.         millis++;
  12.     }
  13.     sleep(millis);
  14.     }

    看到了吧,纳秒——根本就是假的,我们都被JDK骗了。Java常规控制线程的时间精度是非常低的,根本不可能接近纳秒的级别,至于你传入的纳秒参数,下场就是要么变成0,要么变成1毫秒。

 

-------------------------------------------------------我是傻帽的分割线-------------------------------------------------------------------

 

    4、容器类的容量变化的实现:

    以Vector为例吧,找到了一个需要变化容量的方法:

  1. //这是它实际存储对象的数组
  2. protected Object[] elementData;
  3.     private void ensureCapacityHelper(int minCapacity) {
  4.     int oldCapacity = elementData.length;
  5.     if (minCapacity > oldCapacity) {
  6.         Object[] oldData = elementData;
  7.         int newCapacity = (capacityIncrement > 0) ?
  8.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);
  9.             if (newCapacity < minCapacity) {
  10.         newCapacity = minCapacity;
  11.         }
  12.         elementData = new Object[newCapacity];
  13.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  14.     }
  15.     }

    可以看到它的容器大小增长策略,如果有合理的增量,当然听用户的,否则简单地乘2完事。

 

    这只是随便挑了几个JDK的类看一看而已,相信进一步的研究会有更多收获。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值