Join
join方法允許一個線程等待另一個線程運行完畢再繼續。
thread.join();
如果一個線程中包含代碼:
t.join();//導致當前線程暫停,等待線程t執行完畢。可以理解,join也會拋interruptedException。
看完以上的內容,我們就可以看一個包含了上述概念的實際的多線程例子:
http://download.oracle.com/javase/tutorial/essential/concurrency/simple.html
看上去很長其實很簡單,要耐心看~
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());//MessageLoop()必須是runnable同時有run方法。
t.start(); //子線程啟動,開始迴圈列印String數組裡的內容。
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); //這句的效果和sleep(1000)一樣
if (((System.currentTimeMillis() - startTime) > patience) &&
t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt(); //interrupt方法會中斷線程。此時子線程會提示"I wasn't done!",然後被停止。
//Shouldn't be long now -- wait indefinitely
t.join(); //join方法的功能是,當前主線程會等待子線程t結束。不過應該很快。
}
}
threadMessage("Finally!"); //最後程式結束。
}
}
當主線程運行完所有語句,但是有非守護子線程還在運行時,主線程就會一直等待。
(有一點例外。。。如果主線程中最後一句是return。。。那主線程就會立即結束了,從而程式會立即結束)
如果只有守護子線程運行,守護子線程就會結束,之後主線程就運行完畢了。
運行結果:
傳入參數為2時
main: Starting MessageLoop thread
main: Waiting for MessageLoop thread to finish
main: Still waiting...
main: Still waiting...
main: Tired of waiting!
Thread-0: I wasn't done!
main: Finally!