線程一些小知識的整理
一:線程的創建(繼承Thread類方式)
需求: 龜兔賽跑----創建兩個線程,一個線程命名爲兔子Rabbit 一個線程名稱爲烏龜Tortoies
技能: 創建線程並啓動線程
1.創建線程的方式,有兩種,一種是繼承Thread類,一種是實現Runnable接口
2.繼承Thread類----Thread類
2.1 Thread類的定義
線程 是程序中的執行線程。Java 虛擬機允許應用程序併發地運行多個執行線程。
2.2 關於繼承關係,如果一個子類繼承了Thread類,那麼此子類也就是一個線程類了! 所以創建的子類對象,也就是線程對象。
分析: 龍生龍,鳳生鳳,老鼠天生會打洞!
模式:
class 子類名稱 extends Thread {
//重寫run()方法
public void run(){
// 此方法時線程的主體,把核心代碼放入到此方法中!
執行代碼
}
}
2.3 實現Runnable接口---此接口只有一個抽象方法 run()
發現:如果一個子類實現一個接口,此接口如果存在抽象方法,則子類必須重寫!
發現:Thread類和Runnable直接的關係-----實現關係 Thread類實現了Runnable接口
Thread類的構造方法----兩個比較重要的
public Thread(Runnable r);
public Thread (Runnable r, String name)
模式:
class 子類名稱 implements Runnable {
//重寫run()方法
public void run(){
// 此方法時線程的主體,把核心代碼放入到此方法中!
執行代碼
}
}
3.線程的啓動,是調用run()方法還是start()方法?
3.1 如果創建的線程對象,調用的是run()方法,那麼只會把run方法看成是一個普通方法進行執行。
所以,不要直接調用run()方法!
3.2 如果調用的是start()方法,根據API的解釋,JVM會在後臺自動的去調用run()方法
所以,啓動線程是調用start()方法
3.3 發現:在兔子線程當中,啓動之後調用run(),如果run()方法裏面嵌套了一個while死循環
兔子線程一直在執行-----烏龜線程有機會運行嗎?不會執行的
3.4 main方法也是一個線程,而且是主線程
代碼區:
public class Rabbit extends Thread{
//爲什麼不是屬性而是使用構造方法呢?因爲在父類Thread類當中有一個構造方法,public Thread(String name)
public Rabbit(){
}
public Rabbit(String name){
super(name);
}
//重寫run方法
public void run(){
//既然說run方法是線程的主題,把核心代碼放入到此方法中!
while(true){
System.out.println(Thread.currentThread().getName()+"------領先了");
}
}
}
public class Tortoies extends Thread{
//構造方法
public Tortoies(){
}
public Tortoies(String name){
super(name);
}
public void run(){
while(true){
//把核心代碼放入到此方法中
System.out.println(Thread.currentThread().getName()+"------領先了");
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
//開始創建線程
Rabbit r = new Rabbit();
Tortoies t = new Tortoies();
//爲線程命名
/**
* setName()
* getName()
* Thread.currentThread()
* 都是Thread類的方法,子類通過繼承可以調用
*/
r.setName("兔子");
t.setName("烏龜");
//啓動線程
r.start();
t.start();
}
}
二:線程的創建(實現Runnable接口方式)
需求: 大運動會上,運動員進行賽跑----男超人和女超人
技能: 創建線程並啓動線程----實現Runnable接口
問題1: 啓動線程是調用start方法,那麼Runnable接口只有一個run()方法,沒有start方法,怎麼啓動線程?
解決1: 誰有start()方法?---Thread類裏面存在一個start方法 ---- 可以藉助Thread類
發現: Thread類的構造方法
public Thread(Runnable r)
public Thread(Runnable r,String name)
問題2: 創建多個線程,由於併發機制,線程的啓動以及運行,顯得毫無規律
原因2: 線程的隨機性太強---- 體現出各個線程在搶CPU資源,如果那個線程搶到了那麼那個線程執行,可能有的線程一次也不會搶到。
解決2: 可以使用同步鎖
問題3: 發現創建線程的方式有兩種,兩者創建線程的區別?
繼承Thread類
優點: 簡單
缺點: 由於單繼承的線程,無法繼承其他的類
實現Runnable接口
優點: 可以繼承其它類,多線程可共享同一個Runnable對象
代碼區:
public class SuperMan extends Object implements Runnable {
// String name;
//構造方法以及屬性,寫還是不寫? 不寫啦,原因如下:
/*
* 1.如果一個類,沒有定義任何的構造方法,則JVM會默認的配一個孔參構造方法
* 2.創建有參構造方法
* 2.1 通過父類獲取---super(name),發現:SuperMan子類實現的是Runnable接口,不是Thread類
* 2.2 因爲Thread類裏面的構造方法---public Thread(Runnable r,String name)
*/
@Override
public void run() {
//run方法---線程的主題,把核心代碼放入到此方法中
// while(true){
for(int i=1;i<=20;i++){
System.out.println(Thread.currentThread().getName()+"領先了......");
}
}
}
public class SuperWoman implements Runnable {
@Override
public void run() {
// while(true){
for(int i=1;i<=20;i++){
System.out.println(Thread.currentThread().getName()+"領先了");
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
//1.創建Runnable接口對象,目的: 創建線程對象
Runnable r1 = new SuperMan();
// Runnable r2 = new SuperWoman();
//2.如果實現Runnable接口,來創建線程對象,則離不開Thread類
Thread t1 = new Thread(r1,"高宇");
Thread t2 = new Thread(r1,"王夢凡");
//3.啓動線程
t1.start();
t2.start();
}
}
原博地址(也是我,O(∩_∩)O哈哈~):http://m15231417197.lofter.com/
練習代碼地址(嘿嘿嘿):https://download.csdn.net/download/m15231417197/10716486