Java的Thread.run()
方法簡介。
Thread.run()
其實是實作Runnable
介面的run()
。檢視Thread.run()
的原始碼如下。
public class Thread implements Runnable {
// ...
@Override
public void run() {
if (target != null) {
target.run();
}
}
//...
}
從原始碼可以看到,Thread.run()
其實也只是去執行成員變數Runnable target
的run()
而已,而target
就是在建構Thread
物件時傳入的Runnable
參數。
例如建構Thread
時傳入一個Runnable
的實作,當呼叫Thread.run()
時便會去執行Runnable.run()
的實作。
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}, "Thread-a");
a.run();
}
}
所以上面的執行結果會印出
main:0
main:1
main:2
main:3
main:4
從Thread.run()
的原始碼來看,如果建構Thread
物件時沒有傳入Runnable
的實作,因為target == null
,所以呼叫Thread.run()
不會做任何事,例如
public class Test {
public static void main(String[] args) {
Thread a = new Thread();
a.setName("Thread-a");
a.run(); // 執行時沒有任何動作
}
}
所以建構Thread
物件時如果不傳入Runnable
的實作,則應覆寫Thread.run()
方法,執行緒被執行時便會執行run()
的內容。
例如建立一個ThreadA
類別繼承Thread
並覆寫run()
的內容。
public class ThreadA extends Thread {
@Override
public void run(){
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class Test {
public static void main(String[] args) {
Thread a = new ThreadA();
a.setName("Thread-a");
a.run();
}
}
執行結果如下
main:0
main:1
main:2
main:3
main:4
但在寫多執行緒程式時,並不會直接在程式中呼叫Thread.run()
方法來執行,因為在程式中呼叫run()
方法其實都仍只是在原本的執行緒中被執行而已,並沒有執行緒併行(concurrency)的效果。
例如下面雖然新建了兩個執行緒,但都僅是在main執行緒中被依序執行而已
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}, "Thread-a");
Thread b = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}, "Thread-b");
a.run();
b.run();
}
}
執行結果如下,可以看到實際上執行緒的run()
方法僅是在main執行緒中被執行。
main:0
main:1
main:2
main:3
main:4
main:0
main:1
main:2
main:3
main:4
在程式中應該呼叫Thread.start()
來啟動執行緒,此時執行緒便進入可執行(Runnable)狀態,當系統要執行執行緒時便會呼叫執行緒的run()
來執行。
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}, "Thread-a");
Thread b = new Thread(new Runnable(){
@Override
public void run(){
for(int i = 0; i <= 4; i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}, "Thread-b");
a.start(); // 呼叫start()始執行緒進入可執行狀態,待系統安排執行
b.start();
}
}
呼叫start()
後的結果如下,可以看到此時是Thread-a及Thread-b兩條執行緒併行處理。
Thread-a:0
Thread-b:0
Thread-b:1
Thread-a:1
Thread-b:2
Thread-a:2
Thread-b:3
Thread-a:3
Thread-b:4
Thread-a:4
在Java 8可用lambda來寫Runnable
的匿名類別。
public class Main {
public static void main(String[] args) {
Thread a = new Thread(() -> {
int i = 0;
while (i < 5) {
System.out.println(Thread.currentThread().getName() + ":" + i);
i++;
}
}, "Thread-a");
Thread b = new Thread(() -> {
int i = 0;
while (i < 5) {
System.out.println(Thread.currentThread().getName() + ":" + i);
i++;
}
}, "Thread-b");
a.start();
b.start();
}
}
不過執行緒的建立與執行建議使用Java 1.5以後的Executor各實作類別,請參考Java 使用ExecutorService來執行多執行緒。
如果覺得文章有幫助的話還幫忙點個Google廣告,感恩。
參考:
沒有留言:
張貼留言