程式都擁有的,主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