2013年12月20日 星期五

[JAVA] Program,Progress,Thread

  • Program:
    一群程式碼的集合,用以解決特定的問題。在物件導向中相當於類別(Class)。
  • Process:
    由Program所產生的執行個體,一個Program可以同時執行多次產生多個Process。在物件導向中相當於Object。
而 Process又由 Memory Space 和一個以上的 Thread 所組成,其中:

  • Memory Space:相當於Object的variable,不同Process的Memory Space也不同,彼此看不到其他Process的Memory Space。
  • 一個以上的Thread:
    Thread代表從某個起始點開始(例如main),到目前為止所有函數的呼叫路徑,以及這些呼叫路徑上所用到的區域變數。
當然程式的執行狀態,除了紀錄在主記憶體外,CPU內部的暫存器(如Program Counter, Stack Pointer, Program Status Word等)也需要一起紀錄。所以Thread又由下面兩項組成:

  • Stack:紀錄函數呼叫路徑,以及這些函數所用到的區域變數。
  • 目前CPU的狀態。
因此 Thread 的重點如下,一個Process可以有多個Thread。同一Process內的Thread使用相同的Memory Space,但這些Thread各自擁有其Stack。換句話說,Thread能透過reference存取到相同的Object,但是local variable卻是各自獨立的。作業系統會根據Thread的優先權以及已經用掉的CPU時間在不同的Thread作切換,以讓各個Thread都有機會執行。

總之Thread 執行緒常被定義為一個輕量的(Lightweight) Process,可用來處理 request,
然而雖然是輕量,但在產生 Thread 時仍會有 overhead,此時若 request 量太大,
又沒有善加管理這些 Thread 的話,就會拖累整體系統的效能。
為了解決這種類型的效能問題,所以就有了 Thread Pool 的概念產生。

Thread Pool 的概念如同其名,就是一個 Thread 的 Pool,
其中有固定或變動量的 Thread,當 request 進來時,若有閒置的 Thread 就執行,
若沒有的話,可能產生新的 Thread 或把 request 放入 queue 中等待被執行,
當一條 Thread 執行完工作而 queue 中仍有 request 在等待時,
此 Thread 應該要被分發新的 request 並處理。

由以上幾行,我們可以看出 Thread Pool 的工作有:

  1. 管控 Thread 的產生與回收
  2. 分發 Thread 處理 request
  3. 處理 request 的 queue 

[JAVA] Synchronized

簡單介紹
Synchronized使用時,需指定一個物件,系統會Lock此物件,當程式進入Synchrnoized區塊或Method時,該物件會被Lock,直到離開Synchronized時才會被釋放。在Lock期間,鎖定同一物件的其他Synchronized區塊,會因為無法取得物件的Lock而等待。待物件Release Lock後,其他的Synchronized區塊會有一個取得該物件的Lock而可以執行。


各種用法
1. Synchronized Method
synchronized public void syncMethod() {

}

此種synchronized用法鎖定的物件為Method所屬的物件,只要物件被new出超過一個以上的Instance,就有可能保護不到Method內程式。但如果此物件只會被new出一個Instance,譬如new出來後就放到ServletContext,要用的時候從ServletContext中拿出來執行,就可以避免此情況。
2. Synchronized Static Method
synchronized static public void syncMethod() {

}

此種synchronized用法鎖定的物件為Method所屬的物件的Class,不管被new出幾個的Instance,都能夠保證同一個時間只會有一個Thread在執行此Method。
3. Synchronized(this)
public void syncMethod() {
  synchronized(this) {
    …
  }
}

此種synchronized用法與synchronized method用法一樣,都是鎖定Method所屬的物件本身。
4. Synchronized(SomeObject)
public void syncMethod() {
  synchronized(SomeObject) {
    …
  }
}

此種synchronized用法鎖定的是SomeObject,如果SomeObject是同一個Class的兩個不同Instance,那synchronized區塊內就有可能被同時執行。如果每一個Synchronized的SomeObject都是同一個Instance(或者SomeObject本身就是Static),就可以保證區塊內同時間只會有一個Thread執行。
當使用Synchornized(SomeObject)時,SomeObject本身處於被Lock狀態,但此時其他的Thread是可以去更改SomeObject裡面的值,Lock只是同步化的狀態,不表示不能更改資料。


使用時機
Synchronized的使用時機很難定義,比較常見的情況是,當程式中會取出某一個共用的物件且會判斷物件內容值,再更新物件內容,此情況大部分都需要synchronized保護。  

2013年12月19日 星期四

2013年12月16日 星期一

[JAVA] container (轉)

在程式運作中,有時候會需要有地方可以暫時儲存產生出來的物件,我們稱之為 Container(容器)。

而根據目的的不同,在 container 的選擇上也有所不同,例如:

  • List:循序索引的串列結構
  • Set:不允許相同物件存在的集合結構
  • Map:使用 Key-Value(鍵-值) 方式儲存的結構
Collection

在 Java SE 中,Collection 包含了 List 以及 Set。

首先先認識一下 List ,其為 java.util.Collection interface 的 sub interface,而 Collection interface 則是擴充了 Iterable interface,因此其關係如下:

Iterable --> Colllection --> List
而在 J2 SE 5.0 之後,由於增加了 Generic 的功能,因此許多這一類的 Class 都使用 Generic 的功能重新改寫了,因此在查詢 API 時常常會發現 Generic 的使用。

而 List 的特性在於:每個 List 中的元素都是循序加入的,並可透過 index 來存取元素。

然而,List 可使用 Array(java.util.ArrayList) 或是 Linked List(java.util.LinkedList) 來進行實作。而每一種不同的資料結構,適用的情況也不同:

  • ArrayList:處理循序加入以及存取元素方面,效率較佳
  • Linked List:處理經常變動元素排列順序時,效率較佳
接著以下針對由 List 所衍生出來的 container 進行說明:

ArrayList
使用 Array 結構實作 List,而其特性為 index 的應用,因此對於快速取得隨機 object 上效率叫好,但在新增或刪除 object 上,速度就會比 Linked List 慢上許多。

2013年12月15日 星期日

[JAVA] inner class 解析 (轉)

InnerClass 是在JAVA中常見的使用方法
顧名思義,就是有個Class包在另一個Class裡面
如果才接觸JAVA或者對物件導向程式設計並沒有很熟的人,知道這樣就夠了,因為在摸透整個物件設計理念之前,嘗試了解InnerClass 並不是一件聰明的選擇,只會讓人更加頭昏眼花而已@_@ (技能無法使用,需求:物件導向程式設計等級2)
但是如果對JAVA已經有點小熟,你一定已經用過InnerClass ,只是對其使用觀念還有些模糊,這樣的話你就已經解鎖了這項技能,如果你手上還有技能點,請大方地獻給InnerClass 吧!( ̄▽ ̄
難度不高,但是需要一些背景知識
在學習InnerClass 之前,先來了解一下專有名詞吧
1.Member <=>Static Member
=====================
Member: 直屬Class底下的都可稱為Member 
Member 變數稱: instance field
Member Method稱: instance Method
Member Class 就是Member Class
=====================
Static Member變數稱: class field
Static Member Method稱: class Method
Static Member Class 就是Static Member Class
=====================
總之,冠上Static 的東西,就是class 等級的,不需要實體化就可以使用
非Static 的東西就必須要成為instance 才可以使用


2.區域名詞

class ExampleClass{
//field area
//全域

void method(){
//local area
//區域

}
}
這樣一來,InnerClass 會用到的名詞大概都介紹了
名詞介紹可以先不用看得太仔細,寫名詞介紹主要只是為了等一下看InnerClass 時可能會有理解上的困難,或是翻譯上的誤差,用來對照用的╮( ̄▽ ̄)╭

進入正題了…
JAVA中的Class分成2種類
1.一般Class
2.InnerClass (內部類別)
(JAVA沒有像C++的巢狀類別
現在我們要介紹的就是InnerClass

其中InnerClass又有3種狀態,依所存在的位置而決定
中文翻譯使用位置英文原文範例
1.成員式在class中Member inner classclass ExampleClass{
class InnerClass(){
//這就是成員式
//

}
}
2.區域式在method中Local inner class (Local Classes)class ExampleClass{
void method(){
class InnerClass(){
//這就是區域式
//
}
}
}
3.匿名式在宣告同時Anonymous inner class(AIC)class ExampleClass{
void method(){
addActionListener(new ActionListener(){
//這就是匿名式
//
});
}
}

其實下面的才是重點…
這3種InnerClass 可以使用變數的權限,以及被使用的方式(不說方法,怕混淆XD)

innerClass的使用變數權限:
成員式Member inner class
所有field/method均可自由使用

區域式Local inner class
所有field/method均可自由使用
Local variables 必須標記為final才可以使用 ㊟1
 如果Local和Field有同名變數時,預設會選用距離inner class最近的階層,也就是Local的變數
 如果想要使用Field變數,就需要使用到.this.來選用該field

匿名式Anonymous inner class
與Local inner class一樣
其實Anonymous inner class與Local inner class的性質是一樣的


從外部使用innerClass的方法:
使用成員式Member inner class的方法
一般Member Classes: new <ClassName>().new <InnerClassName>();
意思就是必須先取得的實體,再用其new來取得實體
Static Classes: new <ClassName>.<StaticInnerClassName>();
由於Static類別隨時可以取得,因此直接指名取得實體即可

使用區域式Local inner class的方法
無直接取用方法,僅可能透過所屬method回傳,限制也很多,用途也不大,幾乎不這樣使用

㊟1: 為什麼必須標記為final才可以使用?
這個說法我看過2個版本,不過後來經過查證,其中有個說法是錯的…真相只有一個!…咳咳
先說一下錯的版本好了,在JAVA全方位學習這本書中有提到關於這個問題的解釋:因為全域變數會自動給定初始值,而區域變數不會,而編譯器為了避免錯誤出現,限制使用者在區域變數上標記final,來確保變數有值(標上final的變數必須給定值)。雖然聽起來很合理,不過卻不是這個原因 ( ̄︶ ̄)>
正確的版本出現在caterpillar大大的網站中,後來去JAVA英文網站查詢後驗證無誤,解釋應該是這樣的:
Local inner class所在的Method回傳值(return)後,Method中的變數將會被銷毀,因此在Method中,被Local inner class所用到的變數會被複製一份來使用,此時,如果該變數不是final,則複製的變數就可能因為更改而不同步,造成錯亂,因此Local inner class所用到的local variables必須標記為final。
另外,匿名式Anonymous inner class所用到的local variables也必須須標記為final,雖然規定都一樣,但是原因並不同。這裡是因為AIC在實體化時,會將使用到的local variables直接複製並且生成為自己的private變數,同樣的,出現拷貝時,就會有同步的問題,因此該變數也必須被標記為final。

2013年12月13日 星期五

[WCDMA]SDU PDU 解釋

SDUservice Data Unit:服務數據單元,又叫業務數據單元,是指定層的用戶服務的數據集,傳送到接收方的時候同一協議層時數據沒有發生變化,即業務部分,然後發給下層之後,下層將其封裝在PDU中發送出去。服務數據單元是從高層協議來的信息單元傳送到低層協議。第N層服務數據單元SDU,和上一層的協議數據單元(PDU)是一一對應的。根據協議數據單元的數據的不同,送到接收端的指定層。
PDU(N) = SDU(N - 1)
SDU(N) = PDU(N + 1)


PDU:協議數據單元N層用戶與N層協議之間傳遞的數據稱為服務數據單元(SDU) N層協議實體之間傳遞的數據稱為協議數據單元(PDU),通過數據發送/接收管理把用戶提交的SDUPDU的形式,通過下層通道發送到對端協議實體。接收端再將PDU還原成SDU送給收端用戶。PDU的封裝/解封裝:在發送方,將用戶遞交的SDU加上協議控制信息PCI,封裝成PDU;在接收方,講接收到的PDU解封裝,去掉PCI,還原成SDU送交接收方用戶。SDU分段/裝配:如果下層通道的帶寬不能滿足傳遞SDU的需要,就需要將一個SDU分成多段,分別封裝成PDU發送出去(分段);在接收方再將這些PDU解封裝後重新裝配成SDUSDU拼接/分離:拼接是指在發送方(n)層協議實體把多個長度較短的(n)SDU封裝成一個(n)PDU來發送,在接收放再將接收到的(n)PDU解封裝,將多個(n)SDU分離出來。採用拼接功能的目的是提高通道的利用率。PDU分割/組合PDU分割是指在發送端(n)層協議實體把一個(n)PDU分割成多個(n-1)SDU,並行地從多個(n-1)通道發送出去;接收端再將收到的多個(n- 1)SDU組合成一個(n)PDU。由於這是一個N層功能,所以組合操作在N層中進行,即N層先得到多個分割開的(n)PDU,然後把它們組合成一個(n)PDU

2013年12月12日 星期四

[JAVA]abstract class v.s. interface

abstract class 和 interface 的區別

abstract class的特徵:
1. abstract class和abstract method都必須用abstract關鍵字來修飾
2. abstract class不能用new關鍵字去產生物件
3. abstract method只需要宣告, 不需要實作
4. 繼承abstract class的子類別必須實作父類別的abstract method, 否則這子類別還是個abstract class

interface的特徵:
1. interface沒有建構方法 (即method中沒有參數, 且沒有任何變數的設定)
     Ex: interface Bus{
                void sound();
           }
2. interface中所有資料成員都必須初始化, 且均為常數
3. 宣告變數必須是final, static和public
4. interface中的method必須為abstact或public


 abstract class 和 interface 的使用時機

何謂abstract class?

提供一種多個class一起合作工作的方式, 將多個class中相同的元素pull up method到public class中, 再以繼承的方式來使用它, 目的是為了實現"多型"精神


何謂interface?

即spec., 完全不需要定義實作, 只需要函式原型
若要實作interface, 就必須follow它的spec. 

[public] [abstract] interface 介面名稱{
    權限設定  傳回型態  method(parameters); 
    權限設定  傳回型態  method(parameters); 

[public] [abstract]是預設, 所以可省略, 因為interface本身就是抽象的


(註)一個介面可以同時繼承多個介面, 即同時繼承了多個介面的abstract method和常數

 => interface A extends 介面1, 介面2, 介面3, ... 

一個class可以同時實作多個interface
 => class B implements 介面1, 介面2, 介面3, ...