程式都擁有的,主thread製造一個新的thread從Runnable物件,MessageLoop,然後等待他直到結束,如果
MessageLoop thread花太多時間完成他的工作,main thread會中斷他
MessageLoop thread印出一系列的message,如果在他已經印出所有訊息之前中斷,MessageLoop thread印出一個訊息然後離開。
public class SimpleThreads {
//Display a message, preceded by the name of the current thread
static void threadMessage(String message) {
String threadName = Thread.currentThread().getName();
System.out.format("%s: %s%n", threadName, message);
}
private static class MessageLoop implements Runnable {
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try {
for (int i = 0; i < importantInfo.length; i++) {
//Pause for 4 seconds
Thread.sleep(4000);
//Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
}
public static void main(String args[]) throws InterruptedException {
//Delay, in milliseconds before we interrupt MessageLoop
//thread (default one hour).
long patience = 1000 * 60 * 60;
//If command line argument present, gives patience in seconds.
if (args.length > 0) {
try {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be an integer.");
System.exit(1);
}
}
threadMessage("Starting MessageLoop thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for MessageLoop thread to finish");
//loop until MessageLoop thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
//Wait maximum of 1 second for MessageLoop thread to
//finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) > patience) &&
t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt();
//Shouldn't be long now -- wait indefinitely
t.join();
}
}
threadMessage("Finally!");
}
}
輸出結果
main: Starting MessageLoop thread
main: Waiting for MessageLoop thread to finish
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
Thread-0: Mares eat oats
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
Thread-0: Does eat oats
.
.可以嘗試將patience改變,改小一點就會發現Tired of waiting的訊息被傳出來在中斷MessageLoop的時候。
main thread不斷的測試t thread是否存活,並印出Waiting的字樣,然後給予t thread一秒的時間去完成他的事情,直到這一秒一秒累積起來超過了main thread的耐心之後,main thread便會先發出"tired of waiting"的訊息後將t thread中斷掉,t知道自己被interrupt掉之後就發出了InterruptedException,發出"I wasn't done"的訊息然後直接輸出Finally字樣。
可能有人會好奇interrupt方法後面為什麼又要發出join,直覺可能認為是interrupt之後就想要強迫他把剩下內容全部都輸出,不過其實這裡有個盲點,如果在interrupt後面打上一行程式碼
System.out.println(t.getState());
會發現其實這個thread已經terminate了!這時後再給他下join指令其實是一點意義都沒有的,所以可以把join跟interrupt兩行到過來,這樣子就能強迫在thread terminate前把內容輸出了,這樣一來不是更符合沒有耐心的感覺嘛?(笑)
參考網址
http://java.sun.com/docs/books/tutorial/essential/concurrency/simple.html
No comments:
Post a Comment