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廣告,感恩。
參考:
沒有留言:
張貼留言