創建一個線程主要有兩個方法:實現Runnable接口和繼承Thread類。雖然Thread類底層也實現了Runnable接口,但在使用的時候兩者還是有很大差別。
1. 繼承Runnable接口:
public class TestRunnable implements Runnable{ private String name; //給線程一個名稱,方便標識 public TestRunnable(String name){ this.name = name; } @Override public void run(){ for(int i=0; i<10; i++){ System.out.println(name+"正在運行:"+" "+i); } } public static void main(String[] args){ TestRunnable t1 = new TestRunnable("A"); TestRunnable t2 = new TestRunnable("B"); Thread thread1 = new Thread(t1); //用實現Runna接口的對象來創建線程 Thread thread2 = new Thread(t2); thread1.start(); thread2.start(); } }運行結果爲:
A正在運行: 0
B正在運行: 0
A正在運行: 1
B正在運行: 1
A正在運行: 2
B正在運行: 2
A正在運行: 3
A正在運行: 4
B正在運行: 3
A正在運行: 5
B正在運行: 4
A正在運行: 6
B正在運行: 5
A正在運行: 7
B正在運行: 6
A正在運行: 8
B正在運行: 7
A正在運行: 9
B正在運行: 8
B正在運行: 9
再運行一次,發現結果不一樣:
A正在運行: 0
B正在運行: 0
A正在運行: 1
B正在運行: 1
A正在運行: 2
B正在運行: 2
A正在運行: 3
A正在運行: 4
A正在運行: 5
A正在運行: 6
A正在運行: 7
A正在運行: 8
A正在運行: 9
B正在運行: 3
B正在運行: 4
B正在運行: 5
B正在運行: 6
B正在運行: 7
B正在運行: 8
B正在運行: 9
這是因爲每次在運行中,線程都要搶奪CPU資源,由於優先級不同,最終執行的順序和結果也不同。
2. 繼承Thread類:
public class TestThread extends Thread{
private String name;
public TestThread(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + "正在運行 " + i);
}
}
public static void main(String[] args) {
TestThread h1 = new TestThread("A");
TestThread h2 = new TestThread("B");
h1.start();
h2.start();
}
}
運行結果:
A正在運行 0
B正在運行 0
A正在運行 1
B正在運行 1
A正在運行 2
B正在運行 2
A正在運行 3
B正在運行 3
A正在運行 4
B正在運行 4
A正在運行 5
B正在運行 5
A正在運行 6
B正在運行 6
A正在運行 7
B正在運行 7
A正在運行 8
A正在運行 9
B正在運行 8
B正在運行 9
3. Thread與Runnable比較:
看上去Thread的寫法更簡潔,只需要創建對象並start就好。如果不使用公共資源,確實用Thread更方便。但如果有一個變量是多個線程間共享的,怎麼辦?
在TestThread對象中增加一個字段count。
public class TestThread extends Thread{
private String name;
private int count = 10;
public TestThread(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 10; i++) {
--count;
System.out.println(name + "正在運行 " + i + " count還有"+count);
}
}
public static void main(String[] args) {
TestThread h1 = new TestThread("A");
TestThread h2 = new TestThread("B");
h1.start();
h2.start();
}
}
結果怎樣可以猜出來,這根本是兩個對象,各計算各的。
A正在運行 0 count還有9
B正在運行 0 count還有9
B正在運行 1 count還有8
B正在運行 2 count還有7
B正在運行 3 count還有6
B正在運行 4 count還有5
B正在運行 5 count還有4
B正在運行 6 count還有3
B正在運行 7 count還有2
B正在運行 8 count還有1
A正在運行 1 count還有8
B正在運行 9 count還有0
A正在運行 2 count還有7
A正在運行 3 count還有6
A正在運行 4 count還有5
A正在運行 5 count還有4
A正在運行 6 count還有3
A正在運行 7 count還有2
A正在運行 8 count還有1
A正在運行 9 count還有0
那如果換成static類型的變量呢?static爲類的所有對象維護一個公共變量。
A正在運行 0 count還有9
B正在運行 0 count還有8
A正在運行 1 count還有7
B正在運行 1 count還有6
A正在運行 2 count還有5
B正在運行 2 count還有4
A正在運行 3 count還有3
B正在運行 3 count還有2
B正在運行 4 count還有0
B正在運行 5 count還有-1
B正在運行 6 count還有-2
B正在運行 7 count還有-3
B正在運行 8 count還有-4
B正在運行 9 count還有-5
A正在運行 4 count還有1
A正在運行 5 count還有-6
A正在運行 6 count還有-7
A正在運行 7 count還有-8
A正在運行 8 count還有-9
A正在運行 9 count還有-10
乍一看似乎不錯,但如果仔細觀察,會發現順序和數字根本不對。所以用Thread不能正確的實現資源共享。