寫 java 這麼久了,其實直到這次遇到這個狀況我才真的比較搞得清楚所謂 multithread 是怎麼一回事,以前都只是記得觀念,就是一個 process 可以切分成多個 thread 讓他們同時去跑,但到底哪一個 thread 何時會先執行完畢是無法確定的,反正它們會看起來像是同時在執行的樣子。
原因來自於我要解決一個專案裡面產檔跟清檔的功能,在某個 Java Class 裡面的幾個 method 裡,每次執行開始都要產檔(一堆檔),結束之後需要把檔案全部清掉,每個 method 都要這麼做。
但原本產出來的檔名都一樣,怕萬一某個 method 執行完畢要刪在還沒刪除完之前,下個 method 就起來了,可能會造成檔案資料夾下的檔案會有不完整殘留的問題,然後另外一個同事又提出萬一使用者(它們會使用我們開發出去的這份 class)使用 multi thread 來呼叫我們的 class 時可能會有問題。因為一開始我也不太懂所以就想說那用系統時間或是亂數產生資料夾名稱然後再把產生的檔案們都丟進去就好,結束後在一個個把它們清掉。還在比較 java util 的 Random 跟 Math.random 哪個比較好用且適用時,我家小幫手就突然丟給我一個建議說可以用類似 Thread.getId 這個東東,我想說咦? 好像可以喔,但其實根本沒想過啊我的 class 明明就沒有實作 Runnable 壓,使用一般的呼叫方法 new 起來之後,每個 thread 的 id 都會一樣呀 (都是1, 都是主 main thread)。
後來才發現原來要有不同的 thread id 是要將我們執行的 class 放在 new Thread 裡面,所以要馬就是放進去 thread 的那支 class 需要實作 Runnable,然後這樣呼叫 thread.start() (不是呼叫 thread.run() 哦,一開始我還用錯 = =)
eg.
public final class Mpva2 implements Runnable {
public void exec() {
try {
Thread.sleep((int) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread id:" + Thread.currentThread().getId());
exec();
}
}
另外一個 class 用 Thread來呼叫執行 Mpva2:
Thread th1 = new Thread(new Mpva2("1"));
th1.start();
Thread th2 = new Thread(new Mpva2("2"));
th2.start();
執行的結果就會有不同的 thread id:
Thread id:10
Thread id:11
後來我覺得這件事情大概連我同事也不是很清楚,第一是,我們這個 class 並沒有實作 Runnable,所以照理說別人應該也無法透過 multi thread 來叫用,除非他們在外面再包一層有實作 Runnable 的 class 之類。
一開始實作的時候,我用來命名的檔名 System.currentTimeMillis() 還先用成 static final, 感覺這樣好像比較不會一值浪費資源去取得這個值,可是後來發現如果 class 被 new 的時機很近,也會很容易碰到相同系統時間的狀況,因為現在的 cpu 速度都很快壓,連續 new 兩個同樣的 class instance 系統時間也還是很容易一樣無法分辨。
除此之外,在產檔前也需要先檢查是否檔案已存在,若存在要做適當的處理,看是要刪還是要丟例外跟使用者說,總之是很基本但重要的細節。
很多不錯的參考:
Difference between a process and a thread in java
如何在 thread pool 取得 thred id?
Program / Process / Thread 的差別
題外:不禁想到我昨天上瑜珈課 (嗚嗚~超愛的艾楊格瑜珈老師為何才上了三堂就要走了) 老師說,你們做動作的時候要有覺知,有覺知就是要知道你們在做什麼!如果讓頭腦的速度超過身體,身體就會受傷,所以做的時候要等身體可以了才繼續,不要老是跟著頭腦阿,我覺得常常我做事的時候是很無意識的...
很多不錯的參考:
Difference between a process and a thread in java
如何在 thread pool 取得 thred id?
Program / Process / Thread 的差別
沒有留言:
張貼留言