多線程程序實現的方式
一、通過繼承Thread來實現
步驟:
1. 定義類繼承Thread
2. 重寫run方法
3. 把新線程要做的事寫在run方法中
4. 創建線程對象
5. 調用start()方法開啓新線程, 內部會自動執行run方法
示例:
public class Demo2_Thread
{
public static void main(String[] args)
{
//4.創建Thread類的子類對象
MyThread mt = new MyThread();
//5.調用start()方法開啓新線程,系統默認調用run方法
mt.start();
for (int i = 0; i < 1000; i++)
{
System.out.println("bb");
}
}
}
/**
* 創建新執行線程方法一:
* 1.繼承Thread類
* 2.重寫run方法
* 3.將要執行的代碼寫在run方法中
*/
class MyThread extends Thread
{
public void run()
{
for (int i = 0; i < 100; i++)
{
System.out.println("aaaaaaaaaaaaaaa");
}
}
}
二、實現Runnable
步驟:
1. 定義類實現Runnable接口
2. 重寫run方法
3. 把新線程要做的事寫在run方法中
4. 創建自定義的Runnable的子類對象
5. 創建Thread對象, 傳入Runnable
6. 調用start()開啓新線程, 內部會自動調用Runnable的run()方法
示例
public class Demo3_Thread
{
public static void main(String[] args)
{
//4.創建Runnable的子類對象
MyThread mr = new MyThread();
// Runnable target = mr;
//父類引用指向子類對象
//5.將其當作參數傳遞給Thread的構造函數
Thread t = new Thread(mr);
//6.開啓線程
t.start();
for (int i = 0; i < 1000; i++)
{
System.out.println("bb");
}
}
}
//1.定義一個類實現Runnable接口
class MyRunnable implements Runnable
{
@Override
//2.重寫run方法
public void run()
{
//3.將需要執行的代碼放到run方法中
for (int i = 0; i < 1000; i++)
{
System.out.println("aaaaaa");
}
}
}
三、多線程(實現Runnable的原理)
查看源碼 :
1. 看Thread類的構造函數,傳遞了Runnable接口的引用
2. 通過init()方法找到傳遞的target給成員變量的target賦值
3. 查看run方法,發現run方法中有判斷,如果target不爲null就會調用Runnable接口子類對象的run方法
四、多線程(兩種方式的區別)
查看源碼:
1. 繼承Thread: 由於子類重寫了Thread類的run(), 當調用start()時, 直接找子類的run()方法。
2. 實現Runnable : 構造函數中傳入了Runnable的引用, 成員變量記住了它, start()調用run()方法時內部判斷成員變量Runnable的引用是否爲空, 不爲空編譯時看的是Runnable的run(),運行時執行的是子類的run()方法。
繼承Thread(優先考慮)
1. 好處是:可以直接使用Thread類中的方法,代碼簡單
2. 弊端是:如果已經有了父類,就不能用這種方法
實現Runnable接口(若類已有父類,用此方法)
1. 好處是:即使自己定義的線程類有了父類也沒關係,因爲有了父類也可以實現接口,而且接口是可以多實現的
2. 弊端是:不能直接使用Thread中的方法需要先獲取到線程對象後,才能得到Thread的方法,代碼複雜