1,extends Thread類
2,implements Runnable 接口
3,線程池 (暫時沒接觸過)
個人建議:用第二個比較好
因爲Java是單繼承多實現
所以如果用第一種方式的話,該類就無法再繼承其他你想繼承的類。
線程之間的數據共享
1,不共享
線程類代碼
public class MyThread extends Thread{
private int count = 5;
@Override
public void run() {
while(count > 0){
count --;
System.out.println("由 "+ currentThread().getName() + " 計算,count="+count);
}
}
}
public class Test {
public static void main(String[] args) {
MyThread a = new MyThread();
MyThread b = new MyThread();
MyThread c = new MyThread();
a.start();
b.start();
c.start();
}
}
由 Thread-0 計算,count=4
由 Thread-2 計算,count=4
由 Thread-2 計算,count=3
由 Thread-2 計算,count=2
由 Thread-2 計算,count=1
由 Thread-2 計算,count=0
由 Thread-0 計算,count=3
由 Thread-0 計算,count=2
由 Thread-0 計算,count=1
由 Thread-0 計算,count=0
由 Thread-1 計算,count=4
由 Thread-1 計算,count=3
由 Thread-1 計算,count=2
由 Thread-1 計算,count=1
由 Thread-1 計算,count=0
//備註:從Test測試類中可以看出,每個線程都是單獨創建的,有3個MyThread對象,它們調用run方法時候,都是調用自己相應對象中變量,互不干涉。
2,共享
線程類代碼同上
測試類
public class Test {
public static void main(String[] args) {
MyThread thread = new MyThread();
Thread a = new Thread(thread);
Thread b = new Thread(thread);
Thread c = new Thread(thread);
a.start();
b.start();
c.start();
}
}
運行結果:
由 Thread-2 計算,count=3
由 Thread-1 計算,count=2
由 Thread-3 計算,count=2
由 Thread-1 計算,count=0
由 Thread-2 計算,count=1
//備註:從Test測試類中可以看出,新建的三個線程都用到MyThread這個類,所以它們共同使用MyThread中的變量
//爲什麼輸出的順序是亂的?
答案; 因爲start方法只是告訴這個線程要開始運行而已,線程要從CPU中搶到資源纔會執行run方法,而它們誰先搶到CPU資源我們無法控制;
// 爲什麼輸出結果中沒有4且還有相同的值?
答案:線程的順序我們從上面知道是不確定,又因爲count的賦值操作是分三個步驟的
1,取得原有的值
2,計算count-1
3,重新賦值
存在當前線程執行到2的時候,另一個線程執行到1或者3,也就是說,一個線程還沒對count的值處理完的時候,另一個就開始處理了,結果就會看到有很多相同的值出現
//修改下線程類的代碼,如下:
@Override
synchronized public void run() {
while(count > 0){
count --;
System.out.println("由 "+ currentThread().getName() + " 計算,count="+count);
}
}
運行結果:
由 Thread-1 計算,count=4
由 Thread-1 計算,count=3
由 Thread-1 計算,count=2
由 Thread-1 計算,count=1
由 Thread-1 計算,count=0
<span style="font-size: 13.3333px; font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="java">// 關鍵字synchronized的作用是什麼 ?
答案:synchronized起到同步的作用,即當前線程對count沒處理完的時候,其他的線程無法對它進行操作。
//輸出的結果中只有一個線程?
這是因爲我們用synchronized鎖住的是run方法,結果就會一個線程調用run方法,其他的都不會再調用,因爲run方法中有while循環,結果一次就gameover了
解決方法:把while循環去掉