在水木上看到的問題
          int[] intArray = new int[]{1, 2, 3, 4};
          List>Integer< list = new ArrayList>Integer<();
          list.add(1);
          list.add(2);
          list.add(3);
          list.add(4);
          List listFromArray = Arrays.asList(intArray);
          System.out.println(listFromArray);
          System.out.println(list);
          輸出結果是
          [[I@c17164]
          [1, 2, 3, 4]
          也就是說Arrays.asList()并沒有返回一個{1,2,3,4}的List
          原因在于,JDK5中asList接受變長參數表了,把intArray作為單獨的參數傳遞給asList方法的時候,編譯器會把它當作一個Object處理,于是返回了只有一個元素的List,而這個元素應該就是指向int[]的引用。
          解決方法之一是把intArray聲明為Integer[],即
          Integer[] intArray = new Integer[]{new Integer(1), new Integer(2), new Integer(3), new Integer(4)};
          List>Integer< listFromArray2 = Arrays.asList(intArray2);
          System.out.println(listFromArray2);
          這樣就能看到預期結果了

          posted @ 2007-04-22 20:26 ZelluX 閱讀(850) | 評論 (0)編輯 收藏

          posted @ 2007-04-22 20:26 ZelluX 閱讀(804) | 評論 (0)編輯 收藏

          2007-03-24 22:17:50

          繼續保持記筆記的習慣。

          CSS Mastery: Advanced Web Standards Solutions

          1. 應該只在沒有現有元素能夠實現區域分割的情況下使用div元素。如
          >div id="mainNav"<
          >ul<
          >li<1>/li<
          ...
          >/ul<
          >/div<
          就應當使用
          >ul id="mainNav"<
          ...
          >/ul<
          代替

          2. 偽類(Pseudo-classes)
          如a:link a:visited 稱為鏈接偽類,只能用于錨(anchor)元素。
          input:focus tr:hover a:active 稱為動態偽類,理論上可以應用于任何元素。

          3. 通用選擇器(the universal selector)
          * {
          margin: 0px;
          }
          作用于所有元素。

          4. 高級選擇器
          Firefox Safari 均支持,IE 6及更低版本不支持,因此在重要元素上要避免使用。
          1)子選擇器
          如#nav < li僅作用于nav的第一層li,li中包含的列表項不受影響
          2)屬性選擇器
          abbr[title] {border-bottom: 1px dotted #999;}
          abbr[title]:hover {cursor: help;}
          修改了abbr的title屬性,不過第一行貌似在IE7中也沒有效果,Firefox下可以。

          posted @ 2007-04-22 20:25 ZelluX 閱讀(416) | 評論 (0)編輯 收藏

          2007-03-14 10:32:46
          先看完coreservlets, core java把Java學好,恩

          posted @ 2007-04-22 20:25 ZelluX 閱讀(186) | 評論 (0)編輯 收藏

          2007-03-13 16:08:26
          灌個水,Java Bean真是好東西,加上Eclipse的自動寫代碼就更爽了,恩

          posted @ 2007-04-22 20:25 ZelluX 閱讀(340) | 評論 (0)編輯 收藏

          2007-03-02 16:24:28
          新浪的博客編輯器貌似漂亮了不少,還增加了首行自動縮進
          1. 公平性
          創建ReentrantLock對象時,使用true參數可以激活公平鎖策略(fair locking policy):
          Lock fareLock = new ReentrantLock(true);
          公平鎖有助于等待時間最長的線程的恢復運行,當然這種機制也影響了程序性能。公平鎖比普通鎖慢很多,因此默認關閉。
          2. 鎖測試、超時
          線程調用lock方法的時候很有可能停滯,可以使用tryLock()方法代替。獲得鎖成功,tryLock返回true,反之返回false,且線程可以繼續運行。
          可以在tryLock中增加時限參數,如
          if (myLock.tryLock(1000, TimeUnit.MILLISECONDS) ...
          表示時限為1000毫秒,TimeUnit是一個枚舉類,它的值有SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS。
          帶時限參數的tryLock方法和lock方法一樣遵循公平原則,但是無參的tryLock卻不會,不過可以用tryLock(0, TimeOut.SECONES)代替。
          lock方法無法被打斷,如果一個線程在等待鎖的時候被中斷,它會繼續處于停滯狀態,知道獲得鎖為止。而使用帶時限的tryLock方法,如果線程在等待時被中斷,它會拋出InterruptedException異常。這很有用,可以防止程序鎖死的發生。
          類似的還有lockInterruptibly,和tryLock很相似,只是時限無限長。
          Condition也可以設置時限:
          myCondition.await(100, TimeUnit.MILLISECONDS);
          這樣await方法有三種結束的可能:其他線程調用的signal或signalAll方法激活該線程;時限到;線程被中斷(拋出InterruptedException)。
          對于第三種可能,如果不想被中斷(一般很少這樣),調用awaitUninterruptibly方法。
          3. 讀寫鎖
          ReentrantReadWriteLock類用于許多線程從一個數據源讀寫的情況。readLock()和writeLock()返回內置的讀寫鎖。
          4. 為什么stop和suspend方法要被廢棄
          兩個方法有一個共同點:都試圖未經其他線程允許就控制它們的行為。
          首先來看stop方法,這個方法結束了所有執行中的方法,包括run方法,當一個線程被停止的時候,它立即放棄了所有它鎖住的對象,這會使那些對象處于非正常狀態。如轉帳的transferThread在取出資金后存入資金前被停止,就會產生事故。因為一個線程試圖結束另一個線程的時候,它并不知道此時該行為是否安全。
          然后是suspend方法,suspend方法并不會損害對象。但是當你調用suspend方法掛起一個線程時,這個線程擁有的鎖也就同時被掛起了,此時如果調用suspend方法的線程試圖獲得那把鎖,那么整個程序就會鎖死:被掛起的線程需要恢復,能夠恢復它的線程因為鎖而停滯。
          這種情況在GUI中尤為常見,例如銀行用戶界面有暫停和繼續兩個按鈕,暫停按鈕能夠掛起所有運行中的線程,另外paintComponent方法能夠畫出每個帳號的圖表。
          假設某個線程獲得了bank對象的鎖,此時用戶按下了暫停按鈕,所有的轉帳線程掛起,其中一個擁有bank的鎖。由于某個原因,帳號圖表需要重繪,調用了paintComponent方法,后者調用了getBalances方法,又因為無法獲得bank對象的鎖,程序鎖死。而此時用戶自然也無法按下繼續按鈕。
          如果想安全地使用掛起功能,可以自己設計一個suspendRequested變量。
          public void run()
          {
          while (. . .)
          {
          . . .
          if (suspendRequested)
          {
          suspendLock.lock();
          try { while (suspendRequested) suspendCondition.await(); }
          finally { suspendLock.unlock(); }
          }
          }
          }
          public void requestSuspend() { suspendRequested = true; }
          public void requestResume()
          {
          suspendRequested = false;
          suspendLock.lock();
          try { suspendCondition.signalAll(); }
          finally { suspendLock.unlock(); }
          }
          private volatile boolean suspendRequested = false;
          private Lock suspendLock = new ReentrantLock();
          private Condition suspendCondition = suspendLock.newCondition();

          posted @ 2007-04-22 20:25 ZelluX 閱讀(278) | 評論 (0)編輯 收藏

          以空格代替Tab, 養成良好編碼風格

            在編寫程序代碼時用空格代替Tab,可以避免由于編輯器對tab顯示方式不同引起的代碼錯亂,是一種良好的編程風格。

            1. JBuilder
            在Project pane中右鍵點擊項目名稱,在彈出的菜單中選擇"Properties..."以打開項目屬性對話框。再選擇 "Formatting" 屬性選項,把其中的 "Use tab char" 前面的鉤選取消即可。同時還可以在此指定語句塊和折行的縮進空格數目。

            2. Eclipse
            在菜單欄選擇 "Window" - "Preference" 打開自定義對話框。

            (1) 對于java代碼,在 "java - code style -formatter" 中設置。在 "Select a profile" 中選擇 "Java Conversions", 然后點擊 "Show..." 按鈕,把 "Indentation" 屬性的 "Tab Policy" 改成 "Space Only", 同時設置縮進空格數;另外在 "Line Wrapping" 中設置折行的縮進為 1 個indent單位。 點擊 "Apply" 或 "OK" ,將提示你為當前的屬性配置方案另取一個名字。

            (2) 如果使用了MyEclipse, 對于JSP/ HTML/ JavaScript/ XML/ CSS/ SQL/ DTD代碼,要分別在各自的 "Source" 屬性中選中 "indent using spaces", 并設置縮進空格數。

            (3) 以上設置對整個workspace生效,但你還可以單獨設置特定項目的java代碼風格。

            3. UltraEdit
            在“高級”-“配置...”-“編輯”中設置“制表符使用空格代替”。
            另外,在“格式”菜單中還可以選擇對空格和制表符進行相互轉換。

          posted @ 2007-04-22 20:25 ZelluX 閱讀(1950) | 評論 (2)編輯 收藏

          2007-03-01 16:26:54
          omg,打了半天忘了存盤了,運行Java程序時一個crash死機了。。。
          直接把今天看的部分放上來了
          1. The synchronized Keyword
          Before the Lock and Condition interfaces were added to JDK 5.0, the Java language used a different concurrency mechanism. Ever since version 1.0, every object in Java has an implicit lock. If a method is declared with the synchronized keyword, then the object's lock protects the entire method. That is, to call the method, a thread must acquire the object lock.
          In other words,

          public synchronized void method()
          {
          method body
          }

          is the equivalent of

          public void method()
          {
          implicitLock.lock();
          try
          {
          method body
          }
          finally { implicitLock.unlock(); }
          }

          For example, instead of using an explicit lock, we can simply declare the transfer method of the Bank class as synchronized.
          The implicit object lock has a single associated condition. The wait method adds a thread to the wait set, and the notifyAll/notify methods unblock waiting threads. In other words, calling wait or notifyAll is the equivalent of

          implicitCondition.await();
          implicitCondition.signalAll();

          However, the implicit locks and conditions have some limitations. Among them are:
          You cannot interrupt a thread that is trying to acquire a lock.
          You cannot specify a timeout when trying to acquire a lock.
          Having a single condition per lock can be inefficient.
          The virtual machine locking primitives do not map well to the most efficient locking mechanisms available in hardware.
          What should you use in your codeLock and Condition objects or synchronized methods? Here is our recommendation:
          1)It is best to use neither Lock/Condition nor the synchronized keyword. In many situations, you can use one of the mechanisms of the java.util.concurrent package that do all the locking for you. For example, on page 48, you will see how to use a blocking queue to synchronize threads that work on a common task.
          2)If the synchronized keyword works for your situation, by all means, use it. You write less code and have less room for error. Example 1-5 shows the bank example, implemented with synchronized methods.
          3)Use Lock/Condition if you specifically need the additional power that these constructs give you.
          Note: At least for now, using the synchronized keyword has an added benefit. Tools that monitor the virtual machine can report on the implicit locks and conditions, which is helpful for debugging deadlock problems. It will take some time for these tools to be extended to the java.util.concurrent mechanisms.
          2. Monitors
          The locks and conditions are powerful tools for thread synchronization, but they are not very object oriented. For many years, researchers have looked for ways to make multithreading safe without forcing programmers to think about explicit locks. One of the most successful solutions is the monitor concept that was pioneered by Per Brinch Hansen and Tony Hoare in the 1970s. In the terminology of Java, a monitor has these properties:
          ~ A monitor is a class with only private fields.
          ~ Each object of that class has an associated lock.
          ~ All methods are locked by that lock. In other words, if a client calls obj.method(), then the lock for obj is automatically acquired at the beginning of the method call and relinquished when the method returns. Because all fields are private, this arrangement ensures that no thread can access the fields while another thread manipulates them.
          ~ The lock can have any number of associated conditions.
          However, a Java object differs from a monitor in three ways:
          ~ Fields are not required to be private.
          ~ Methods are not required to be synchronized.
          ~ The lock has only one condition.
          This disrespect for security enraged Per Brinch Hansen. In a scathing review of the multithreading primitives in Java, he wrote: "It is astounding to me that Java's insecure parallelism is taken seriously by the programming community, a quarter of a century after the invention of monitors and Concurrent Pascal. It has no merit." [Java's Insecure Parallelism, ACM SIGPLAN Notices 34:3845, April 1999]
          3. Synchronized Blocks
          Recall that each object has a lock. A thread can acquire the lock in one of two ways, by calling a synchronized method or by entering a synchronized block. If the thread calls obj.method(), it acquires the lock for obj. Similarly, if a thread enters a block of the form

          synchronized (obj) // this is the syntax for a synchronized block
          {
          critical section
          }
          then the thread acquires the lock for obj. The lock is reentrant. If a thread has acquired the lock, it can acquire it again, incrementing the hold count. In particular, a synchronized method can call other synchronized methods with the same implicit parameter without having to wait for the lock.
          It is legal to declare static methods as synchronized. If such a method is called, it acquires the lock of the associated class object. For example, if the Bank class has a static synchronized method, then the lock of the Bank.class object is locked when it is called.
          4. Volatile 域
          現在的處理器和編譯器很有可能產生一些同步時的錯誤:
          ~ 多處理器的計算機會臨時地在寄存器或緩存中存放數據,因此在不同處理器上運行的線程可能會從同一個內存區域獲得不同的值。
          ~ 編譯器為了提高效率,會重新排列指令順序。但它們在操作時假設只有當有明確的更改指令時,內存數據才會改變。然而,實際上該數據有可能被另一線程修改。
          如果你用鎖保護由多線程訪問的代碼,就不會遇到這些問題。編譯器在清洗緩沖區時會考慮到鎖的存在,也不會錯誤地修改指令順序。具體細節參見http://www.jcp.org/en/jsr/detail?id=133http://www-106.ibm.com/developerworks/java/library/j-jtp02244.html
          Brian Goetz指出了應該何時使用同步:當你更改了某個下次可能會被其他線程訪問的變量,或者訪問了一個上一次可能被其他線程修改的變量,你就必須使用synchronization。
          volatile關鍵字提供了一種同步實例域的訪問的機制。如果把某一字段聲明為volatile,編譯器和虛擬機就會考慮到該數據域可能會同時被另一線程訪問。
          例如,boolean值的字段done可能被一個線程修改,并由另一個線程訪問。有兩種方法實現:
          1)
          public synchronized boolean isDone() {return done;}
          private boolean done;
          這種方法有一個潛在的缺陷:如果另一個方法鎖住了對象,isDone方法可能會停滯。
          2)
          public boolean isDone() {return done;}
          private volatile boolean done;
          當然,訪問一個volatile字段會比訪問普通字段慢一些。
          總結一下,對某字段的并發訪問在以下情況中是安全的:
          ~ volatile字段
          ~ final字段,并且在構造器完成后就被修改。
          ~ 訪問操作被鎖保護
          5. 鎖死 Deadlocks
          死鎖的幾種情況:(以銀行轉帳為例)
          1)帳號1: $2,000 帳號2: $3,000
          先試圖從帳號1轉3000到帳號2,再試圖從帳號2轉4000到帳號1。
          容易得出,最后兩個線程都會鎖死。
          2)有許多帳號,其中
          帳號1: $1,990 其余帳號都是 $990
          線程1: 從帳號1轉$995到帳號2
          其余線程: 從自己的帳號轉出$995到其他帳號
          顯然,除了線程1,其余線程都被停滯。
          線程1操作后,帳號1剩$995,帳號2剩$1,985,此時線程1使用signal方法隨機恢復了一個線程,假設是線程3,但恢復后發現帳號3的資金仍不夠轉帳,于是繼續停滯。
          假設此時線程1又執行了從帳號1轉出$997的指令,于是線程1也停滯。
          系統鎖死。
          罪魁禍首就是signal方法。

          posted @ 2007-04-22 20:25 ZelluX 閱讀(359) | 評論 (0)編輯 收藏

          2007-02-28 16:34:52
          *
          Condition只是一個接口,怎么可以直接調用它的方法呢?于是查源碼(發現這個東西才是最徹底的),從ReentrantLock開始,
          ReentrantLock.newCondition()
          -
          -
          -
          看到了詳細的方法實現 ^_^
          1. 兩三個線程同時修改某個對象,如果僅由訪問先后來決定結果的話,會出現各種結果。這種情況被稱為race condition。
          2. 防止這種情況的發生,必須知道如何同步訪問(synchronize the access)。
          3. javap -c -v ClassName 可以反編譯一個.class文件。
          4. 鎖住對象
          早期版本的Java使用synchronized關鍵詞,JDK5以后引入了ReentrantLock類。
          使用ReentrantLock類保護代碼塊的基本輪廓:
          myLock.lock(); // a ReentrantLock object
          try
          {
          critical section
          }
          finally
          {
          myLock.unlock(); // make sure the lock is unlocked even if an exception is thrown
          }
          這樣第一個線程調用lock方法鎖住myLock后,第二個線程調用lock方法就會被block,并且得等到第一個線程調用myLock.unlock()后才能繼續。
          ReentrantLock類允許被多次鎖定,它記錄了呼叫的嵌套形式。大致是這個意思,原文是

          The lock is called reentrant because a thread can repeatedly acquire a lock that it already owns. The lock keeps a hold count that keeps track of the nested calls to the lock method. The thread has to call unlock for every call to lock in order to relinquish the lock. Because of this feature, code that is protected by a lock can call another method that uses the same locks.

          For example, the TRansfer method calls the getTotalBalance method, which also locks the bankLock object, which now has a hold count of 2. When the getTotalBalance method exits, the hold count is back to 1. When the transfer method exits, the hold count is 0, and the thread relinquishes the lock.

          In general, you will want to protect blocks of code that require multiple operations to update or inspect a data structure. You are then assured that these operations run to completion before another thread can use the same object.

          5. Condition Objects
          Conditon Objects用來管理得了訪問權,卻實際并不能做有用功的線程。
          以銀行帳戶轉帳為例,轉帳時要確定轉出源的資金數不少于要轉出的金額。
          首先不能這樣簡單的寫代碼:
          if (bank.getBalance(from) <= amount)
          bank.transfer(from, to, amount);
          這種代碼完全有可能在if語句判斷完成后,transfer之前停滯,這樣在調用transfer的時候,可能帳戶當前的資金已經不是if語句判斷那個時候的數目了。
          也就是說,測試可行性和實際操作必須一起進行,之間不能有中斷。
          可以用一個lock把測試和操作綁定起來:
          public void transfer(int from, int to, int amount)
          {
          bankLock.lock();
          try
          {
          while (accounts[from] > amount)
          {
          // wait
          . . .
          }
          // transfer funds
          . . .
          }
          finally
          {
          bankLock.unlock();
          }
          }
          這樣還是有問題,帳戶資金不夠移出時,會困在while塊中等待資金撥入這個帳戶,但由于bankLock已經被鎖定,所以其他線程不能進行撥入操作,進入了死循環。這就是condition object產生的原因。
          一個lock對象可以有一個或多個相關的condition object,可以通過newCondition方法獲得一個條件對象,通常用實際條件命名每個條件對象,如
          class Bank
          {
          public Bank()
          {
          . . .
          sufficientFunds = bankLock.newCondition();
          }
          . . .
          private Condition sufficientFunds;
          }
          當transfer方法發現當前資金不夠時,調用
          sufficientFunds.await();
          這樣當前線程就會停滯,并解除lock。
          await方法調用后,線程進入對應Condition的等待區,直到另一個線程調用同一Condition的signalAll方法才會解除block狀態,并等待再次被線程管理器激活。
          如果一個線程調用了condition.await方法,卻沒有其他線程調用condition.signalAll,這個線程就進入了deadlock情況。如果所有其他的線程都進入了等待區,而最后一個線程也調用了condition.await,那么整個程序就掛起了。
          因此最好的調用signalAll的時機是在每次對象的狀態被改變,而這個改變有可能使得等待區的線程有進展的時候。如Bank中每次成功轉帳之后。
          另一個方法,signal,僅僅從等待區中隨機選擇一個進程并釋放。
          注意:線程只能在獲得了lock權以后才能調用condition的await, signal, 和signalAll。

          posted @ 2007-04-22 20:25 ZelluX 閱讀(331) | 評論 (0)編輯 收藏

          2007-02-28 14:05:52
          1. 線程優先權
          每個線程都有一定的優先權,且默認從父線程繼承優先權,也就是運行這個線程的線程。可以使用setPriority方法設置,從MIN_PRIORITY(1)到MAX_PRIORITY(10),NORM_PRIORITY是5。
          然而線程優先權更多的是由系統決定的。如在WinXP/NT有若干個優先等級,某些Java的優先級也自動對應到相應的等級上。但是在Sun JVM for Linux中,線程優先權被忽視,所有的線程享有相同的優先權。
          所以,最好把線程僅僅看成是對線程管理器的hint。不要由線程優先級來決定你的程序結構。
          注意:在使用優先級的時候,如果某幾個很少會停滯的線程享有高優先級,很有可能低優先級的線程就不會被運行。
          2. Daemon進程
          把一個進程變為daemon進程可以調用方法setDaemon(true)。所謂daemon,就是只用來服務其他進程的進程,所以當只有daemon進程運行時,JVM就退出了。
          3. 進程組
          ThreadGroup g = new ThreadGroup(String groupName);
          注意groupName必須唯一。
          加入線程:
          Thread t = new Thread(g, String threadName);
          進程組中可以有子進程組,新創建的子進程組默認屬于當前進程組。
          ThreadGroup類的方法:
          int activeCount() 返回組中活動的線程數。
          int enumerate(Thread[] list) 獲得組中每個活動進程的引用,返回實際加入list的進程數。
          ThreadGroup getParent()
          void interrupt 中止所有的進程和子進程組。
          4. 處理未捕獲異常
          線程的run方法并不能拋出任何checked異常,但因為一個unchecked異常而結束。
          在線程結束前,異常會被傳遞給一個處理器。
          異常處理器必須實現了Thread.UncaughtExceptionHandler接口,后者只有一個方法
          void uncaughtException(Thread t, Throwable e)
          可以在任何線程中使用setUncaughtExceptionHandler方法設置處理器,也可以使用Thread的靜態方法setDefaultUncaughtExceptionHandler為每個線程指定默認的處理器。如果不為每個獨立的線程指定處理器,處理器默認為該線程的線程組對象。
          ThreadGroup類實現了Thread.UncaughtExceptionHandler接口,它的uncaughtException方法按下列步驟進行:
          1)如果該進程組有父進程組,調用父進程組的uncaughtException方法。
          2)否則,如果Thread.getDefaultUncaughtExceptionHandler返回一個非null的引用,該處理器被調用。
          3)如果仍未找到,且Throwable參數是ThreadDeath的實例,不進行任何處理。
          4)上述都未執行的話,進程名和Throwable參數的調用棧就會輸出到System.err上

          posted @ 2007-04-22 20:25 ZelluX 閱讀(285) | 評論 (0)編輯 收藏

          僅列出標題
          共39頁: First 上一頁 28 29 30 31 32 33 34 35 36 下一頁 Last 
          posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
          主站蜘蛛池模板: 教育| 巴彦县| 荔波县| 鞍山市| 双鸭山市| 澄江县| 苏尼特左旗| 资溪县| 济南市| 巧家县| 叙永县| 巩留县| 潞西市| 岳普湖县| 太保市| 翼城县| 长白| 定西市| 工布江达县| 永丰县| 阳信县| 博罗县| 东台市| 白城市| 彭水| 潢川县| 保亭| 平度市| 永州市| 黔东| 哈尔滨市| 囊谦县| 灵寿县| 砀山县| 伊吾县| 长武县| 新晃| 旺苍县| 卓尼县| 新龙县| 津南区|