中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

黑馬程序員——多線程篇

發布時間:2020-04-29 19:26:50 來源:網絡 閱讀:448 作者:optimisticpig 欄目:移動開發

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



   進程:正在執行的程序。

   線程:是進程中用于控制程序執行的控制單元(執行路徑,執行情景),進程中至少有一個線程。

   對于JVM,啟動時,只好有兩個線程:jvm的主線程。jvm的垃圾回收線程。


如何在程序中自定義線程呢?

   Java給我們提供了對象線程這類事物的描述。該類是Thread。該類中定義了,創建線程對象的方法(構造函數),提供了要被線程執行的代碼存儲的位置(run());還定義了開啟線程運行的方法(start()).同時還有一些其他的方法用于操作線程:static Thread currentThead();String getName();static void sleep(time)throws InterruptedException;要運行的代碼都是后期定義的。

   創建線程的第一種方式是:繼承Thread類。原因:要覆蓋run方法,定義線程要運行的代碼。

   步驟:

       1,繼承Thread類。

       2,覆蓋run方法。將線程要運行的代碼定義其中。

       3,創建Thread類的子類對象,其實就是在創建線程,調用start方法。

   創建線程的第二種方式:實現Runnable接口。

   步驟:

       1,定義了實現Runnable接口。

       2,覆蓋接口的run方法。將多線程要運行的代碼存入其中。

       3,創建Thread類的對象(創建線程),并將Runnable接口的子類對象作為參數傳遞給Thread的構造函數。

           為什么要傳遞?因為線程要運行的代碼都在Runnable子類的run方法中存儲。所以要將該run方法所屬的對象傳遞給Thread。讓Thread線程去使用該對象調用其run方法。

       4,調用Thread對象的start方法。開啟線程。

   兩種方式的特點:

       實現方式,因為避免了單繼承的局限性,所以創建線程建議使用第二種方式。


   線程狀態:

       被創建:start()

       運行:具備執行資格,同時具備執行權;

       凍結:sleep(time),wait()—notify()喚醒;線程釋放了執行權,同時釋放執行資格;

       臨時阻塞狀態:線程具備cpu的執行資格,沒有cpu的執行權;

       消亡:stop()

黑馬程序員——多線程篇


   多線程具備隨機性。因為是由cpu不斷的快速切換造成的。就有可能會產生多線程的安全問題。

   問題的產生的原因:

   幾個關鍵點:

       1,多線程代碼中有操作共享數據。

       2,多條語句操作該共享數據。

   當具備兩個關鍵點時,有一個線程對多條操作共享數據的代碼執行的一部分。還沒有執行完,另一個線程開始參與執行。就會發生數據錯誤。

   解決方法:

   當一個線程在執行多條操作共享數據代碼時,其他線程即使獲取了執行權,也不可以參與操作。


同步

   同步的原理:就是將部分操作功能數據的代碼進行加鎖。


   同步的表現形式:

   1,同步代碼塊。

   2,同步函數。

   兩者有什么不同:

       同步代碼塊使用的鎖是任意對象。

       同步函數使用的鎖是this。

   注意:對于static的同步函數,使用的鎖不是this。是 類名.class 是該類的字節碼文件對象。


   同步的好處:解決了線程的安全問題。

         弊端:較為消耗資源。同步嵌套后,容易死鎖。


   要記住:同步使用的前提:

       1,必須是兩個或者兩個以上的線程。

       2,必須是多個線程使用同一個鎖。

       這是才可以稱為這些線程被同步了。

死鎖代碼:

class Test implements Runnable
{
    private boolean flag;//定義標記,用于調節兩個線程的運行。
    Test(boolean flag)
    {
        this.flag = flag;
    }
    public void run()
    {
        if (flag)
        {
            while (true)
            {          
                synchronized(MyLock.locka)
                {
                    System.out.println("if locka");//線程t1需要MyLock.lockb,但是else的MyLock.lockb內有t2。
                    synchronized(MyLock.lockb)
                    {
                        System.out.println("if lockb");
                    }
                }
            }
        }
        else
        {
            while (true)
            {          
                synchronized(MyLock.lockb)
                {
                    System.out.println("else lockb");//線程t2需要MyLock.locka,但是if的MyLock.locka內有t1。
                    synchronized(MyLock.locka)
                    {
                        System.out.println("else locka");
                    }
                }
            }
        }
    }
}
class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();
}
class DeadLockTest
{
    public static void main(String[] args)
    {
        //該線程運行if語句。
        Thread t1 = new Thread(new Test(true));
                                      
        //該線程運行else語句。
        Thread t2 = new Thread(new Test(false));
        t1.start();
        t2.start();
    }
}

   java.lang.Thread 的方法


       interrupt():中斷線程。

       setPriority(int newPriority):更改線程的優先級。

       getPriority():返回線程的優先級。

       toString():返回該線程的字符串表示形式,包括線程名稱、優先級和線程組。

       Thread.yield():暫停當前正在執行的線程對象,并執行其他線程。

       setDaemon(true):將該線程標記為守護線程或用戶線程。將該線程標記為守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。該方法必須在啟動線程前調用。

       join:臨時加入一個線程的時候可以使用join方法。當A線程執行到了B線程的join方式。A線程處于凍結狀態,釋放了執行權,B開始執行。A什么時候執行呢?只有當B線程運行結束后,A才從凍結狀態恢復運行狀態執行。


JKD1.5中提供了多線程升級解決方案。

將同步synchronized替換成顯式的Lock操作。

將Object中的wait,notify,notifyAll,替換了Condition對象。該對象可以Lock鎖獲取。


在該示例中,實現了本方只喚醒對方的操作。

class Test implements Runnable
{
    private boolean flag;//定義標記,用于調節兩個線程的運行。
    Test(boolean flag)
    {
        this.flag = flag;
    }
    public void run()
    {
        if (flag)
        {
            while (true)
            {          
                synchronized(MyLock.locka)
                {
                    System.out.println("if locka");//線程t1需要MyLock.lockb,但是else的MyLock.lockb內有t2。
                    synchronized(MyLock.lockb)
                    {
                        System.out.println("if lockb");
                    }
                }
            }
        }
        else
        {
            while (true)
            {          
                synchronized(MyLock.lockb)
                {
                    System.out.println("else lockb");//線程t2需要MyLock.locka,但是if的MyLock.locka內有t1。
                    synchronized(MyLock.locka)
                    {
                        System.out.println("else locka");
                    }
                }
            }
        }
    }
}
class MyLock
{
    static Object locka = new Object();
    static Object lockb = new Object();
}
class DeadLockTest
{
    public static void main(String[] args)
    {
        //該線程運行if語句。
        Thread t1 = new Thread(new Test(true));
          
        //該線程運行else語句。
        Thread t2 = new Thread(new Test(false));
        t1.start();
        t2.start();
    }
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清水县| 华阴市| 平泉县| 乌拉特前旗| 卓尼县| 奉节县| 泸定县| 屏南县| 抚远县| 革吉县| 徐州市| 青铜峡市| 义马市| 镇赉县| 沿河| 乾安县| 宾川县| 洪洞县| 镇安县| 鄂托克前旗| 富顺县| 安多县| 定边县| 云梦县| 乐安县| 政和县| 逊克县| 博野县| 崇仁县| 东宁县| 银川市| 托克逊县| 平定县| 紫云| 广丰县| 隆化县| 历史| 宝兴县| 青田县| 白沙| 昆山市|