黑馬程序員-多線程部分(一.創建)

——- android培訓java培訓、期待與您交流! ———

學習多線程之前,我們需要知道爲什麼要學習多線程?首先需要明確以下三點內容:

 
第一點: 什麼是進程?什麼是線程?
任何一個應用程序開啓後都是一個進程,進程是由window/linux系統啓動的。線程是進程開啓後運行的操作控制單元,或者稱爲執行路徑, 一個進程至少有一個線程。對於任何一個java程序,實際上開啓的是兩個線程,一個是main順序執行的順序線程,一個是系統自帶的gc垃圾回收線程。這樣做的好處是一方面保證了內存的空間,一方面保證了運行速度不受影響。
第二點:多線程的理解?
當一個進程中開啓多個線程時,顯示的爲這多個線程同時在執行,而實際上如果只有一個CPU處理器時,CPU是隨機選擇執行某一個線程的,由於CPU高速切換的特性,看起來好像多個線程在同時執行,這是看哪個線程率先搶佔CPU的執行權,但在某一時刻,一個CPU是隻執行一個線程的。 多線程就是一個線程裏面有兩個或兩個以上線程可以一起執行,都具備CPU執行資格,也都可以輪流運行。
第三點:多線程的作用?
多線程可以使多個程序同時運行,提高了運行效率。
明白以上三點,首先我們學校多線程的創建方式。

一個線程的創建方式有兩種:

(一)使用Thread類完成,創建步驟如下:

步驟一:一個子類繼承Thread類
步驟二:覆寫run方法

class Test extends Thread
{
    void run()
    {
        for(int i=0;i<100;i++)
        {
            System.out.println("test......."+i);
        }
    }
}

步驟三:實例化對象,調用start方法。

public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        test.start();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}

運行結果如下:
這裏寫圖片描述
main線程和test線程交替運行。
在這裏,多線程執行的是run()方法裏面的代碼塊,調用start()方法有兩個作用,一是開啓該線程,二是調用run()方法。此處不應該直接調用run()方法,如下代碼會出現錯誤:

public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        test.run();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}

運行結果:
這裏寫圖片描述
顯示爲先執行test的run方法,後執行main以後的代碼,此爲單線程。
需要說明一點:如果沒有調用start方法,實際上等於沒有開啓多線程,只是簡單的在main線程中調用run方法而已,實際上只有一個main線程,而非是多線程。

(二)實現runnable接口,開啓線程。 實現步驟如下 :

步驟一:實現runnable接口
步驟二:覆寫runnable接口中的run方法 。

class Test implements Runnable
{
    public void run()
    {
        for(int i=0;i<100;i++)
        {
            System.out.println("test......."+i);
        }
    }
}

步驟三:實例化實現runnable接口的子類對象
步驟四:實例化Thread類,並把實現runnable接口的子類對象傳遞到構造方法中
步驟五:調用啓動線程方法start()

public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        Thread t = new Thread(test);
        t.start();
        for(int i=0;i<90;i++)
        {
            System.out.println("main......."+i);
        }
    }
}

在這裏,與Thread唯一的不同是,在Thread實例化時,將runnable接口的子類傳入到構造方法中即可實現。

以上兩種方法爲簡單的創建多線程,那麼二者有什麼區別和聯繫呢?

1). 如果該類繼承了其他類,則不可繼承Thread類;或者繼承了Thread類則不可繼承其他類,而使用runnable接口則不會出現這種情況,避免了單繼承的侷限。
2). 使用runnable接口,則可以實現資源共享。不用定義爲static即可。
一般情況,建議使用runnable接口的方法開啓線程。

第一點比較容易理解,下面看一下第二點,利用代碼說明。
例子:一共50張票,4個窗口同時買票。

首先用Thread實現:

class Test extends Thread
{
    private int ticket = 50;
    public void run()
    {
        while(true)
        {
            if(ticket>0)
            {
            System.out.println("ticket......."+ticket--);
            }
        }

    }
}
public class ThreadDemo
{
    public static void main(String args[])
    {
        Test t1 = new Test();
        Test t2 = new Test();
        Test t3 = new Test();
        Test t4 = new Test();
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

運行結果如下:
這裏寫圖片描述
結果顯示,四個線程分別執行了50張票,沒有共享數據,造成數據錯誤。
在此用Runnable實現:

class Test implements Runnable
{
    private int ticket = 50;
    public void run()
    {
        while(true)
        {
            if(ticket>0)
            {
            System.out.println("ticket......."+ticket--);
            }
        }

    }
}
public class ThreadDemo
{
    public static void main(String args[])
    {
        Test test = new Test();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        Thread t3 = new Thread(test);
        Thread t4 = new Thread(test);
        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }
}

運行結果如下:
這裏寫圖片描述
而一個Runnable子類被傳遞到四個線程中,可以共享數據,從而避免了數據錯誤。

好了,到此爲止,多線程創建部分已經完成了,下一集介紹多線程的多線程的數據安全問題,利用線程同步來解決。敬請期待。 本人也是初學者,有什麼問題請指出,共同商討。

發佈了32 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章