天天看點

【百度網盤分享】Java基礎總結

多線程:

1、程序和線程:

        程序:正在進行的程式。每一個程序執行都有一個執行順序,該順序是一個執行路徑,或者叫一個控制單元。

        線程:程序内部的一條執行路徑或者一個控制單元。

        兩者的差別:

                一個程序至少有一個線程

                程序在執行過程中擁有獨立的記憶體單元,而多個線程共享記憶體;

2、jvm多線程的啟動是多線程嗎?

        java的虛拟機jvm啟動的是單線程,就有發生記憶體洩露的可能,而我們使用java程式沒出現這樣的問題,

        也就是jvm啟動至少有兩個線程,一個執行java程式,一個執行垃圾回收。是以是多線程。       

2、多線程的優勢:

        解決了多部分同時運作的問題,提高效率

3、線程的弊端:

        線程太多會導緻效率的降低,因為線程的執行依靠的是CPU的來回切換。

4、什麼叫多線程:

        一個程序中有多個線程,稱為多線程。

5、實作多線程的方法:

        實作多線程可以通過繼承Thread類和實作Runnable接口。

        (1)繼承Thread

            定義一個類繼承Thread類

            複寫Thread類中的public void run()方法,将線程的任務代碼封裝到run方法中

            直接建立Thread的子類對象,建立線程

            調用start()方法,開啟線程(調用線程的任務run方法)

            //另外可以通過Thread的getName()擷取線程的名稱。

        (2)實作Runnable接口;

                定義一個類,實作Runnable接口;

                覆寫接口的public void run()的方法,将線程的任務代碼封裝到run方法中;

                建立Runnable接口的子類對象

                将Runnabl接口的子類對象作為參數傳遞給Thread類的構造函數,建立Thread類對象

                       (原因:線程的任務都封裝在Runnable接口子類對象的run方法中。

                         是以要線上程對象建立時就必須明确要運作的任務)。

                調用start()方法,啟動線程。

        兩種方法差別:

                (1)實作Runnable接口避免了單繼承的局限性

                (2)繼承Thread類線程代碼存放在Thread子類的run方法中

                   實作Runnable接口線程代碼存放在接口的子類的run方法中;

                   在定義線程時,建議使用實作Runnable接口,因為幾乎所有多線程都可以使用這種方式實作

6、建立線程是為什麼要複寫run方法?

        Thread類用于描述線程。Thread類定義了一個功能,用于存儲線程要運作的代碼,該存儲功能就是run方法。

7、start()和run方法有什麼差別?

        調用start方法方可啟動線程,而run方法隻是thread的一個普通方法,調用run方法不能實作多線程;

        Start()方法:

                start方法用來啟動線程,實作了多線程運作,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的

                代碼。通過調用Thread類的start()方法來啟動一個線程,這時此線程處于就緒(可運作)狀态,并沒有運作,

                一旦得到cpu時間片(執行權),就開始執行run()方法,這裡方法run()稱為線程體,

                它包含了要執行的這個線程的内容,Run方法運作結束,此線程随即終止。       

        Run()方法:

                run()方法隻是Thread類的一個普通方法,如果直接調用Run方法,程式中依然隻有主線程這一個線程,

                其程式執行路徑還是隻有一條,還是要等待run方法體執行完畢後才可繼續執行下面的代碼,

                這樣就沒有達到多線程的目的。

8、線程的幾種狀态:

        建立:new一個Thread對象或者其子類對象就是建立一個線程,當一個線程對象被建立,但是沒有開啟,這個時候,

              隻是對象線程對象開辟了記憶體空間和初始化資料。                

        就緒:建立的對象調用start方法,就開啟了線程,線程就到了就緒狀态。

              在這個狀态的線程對象,具有執行資格,沒有執行權。

        運作:當線程對象擷取到了CPU的資源。

              在這個狀态的線程對象,既有執行資格,也有執行權。

        當機:運作過程中的線程由于某些原因(比如wait,sleep),釋放了執行資格和執行權。

              當然,他們可以回到運作狀态。隻不過,不是直接回到。

              而是先回到就緒狀态。

        死亡:當線程對象調用的run方法結束,或者直接調用stop方法,就讓線程對象死亡,在記憶體中變成了垃圾。                     

9、sleep()和wait()的差別:

         (1)這兩個方法來自不同的類,sleep()來自Thread類,和wait()來自Object類。

         (2)sleep是Thread的靜态類方法,誰調用的誰去睡覺,即使在a線程裡調用了b的sleep方法,實際上還是a去睡覺,

            要讓b線程睡覺要在b的代碼中調用sleep。而wait()是Object類的非靜态方法

         (3)sleep()釋放資源不釋放鎖,而wait()釋放資源釋放鎖;

         (4)使用範圍:wait,notify和notifyAll隻能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用

10、多線程安全問題:

        (1)原因:當程式的多條語句在操作線程共享資料時(如買票例子中的票就是共享資源),由于線程的随機性導緻

                一個線程對多條語句,執行了一部分還沒執行完,另一個線程搶奪到cpu執行權參與進來執行,

                此時就導緻共享資料發生錯誤。比如買票例子中列印重票和錯票的情況。       

        (2)解決方法:對多條操作共享資料的語句進行同步,一個線程在執行過程中其他線程不可以參與進來

11、Java中多線程同步是什麼?

         同步是用來解決多線程的安全問題的,在多線程中,同步能控制對共享資料的通路。如果沒有同步,當一個線程在

         修改一個共享資料時,而另外一個線程正在使用或者更新同一個共享資料,這樣容易導緻程式出現錯誤的結果。

12、什麼是鎖?鎖的作用是什麼?

        鎖就是對象

        鎖的作用是保證線程同步,解決線程安全問題。

        持有鎖的線程可以在同步中執行,沒有鎖的線程即使獲得cpu執行權,也進不去。

13、同步的前提:

        (1)必須保證有兩個以上線程

        (2)必須是多個線程使用同一個鎖,即多條語句在操作線程共享資料

        (3)必須保證同步中隻有一個線程在運作

14、同步的好處和弊端

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

        弊端:多線程都需要判斷鎖,比較消耗資源

15、同步的兩種表現形式:

        (1)同步代碼塊:

                可以指定需要擷取哪個對象的同步鎖,使用synchronized的代碼塊同樣需要鎖,但他的鎖可以是任意對象

                考慮到安全問題,一般還是使用同一個對象,相對來說效率較高。

                注意:

                **雖然同步代碼快的鎖可以使任何對象,但是在進行多線程通信使用同步代碼快時,

                  必須保證同步代碼快的鎖的對象和,否則會報錯。

                **同步函數的鎖是this,也要保證同步函數的鎖的對象和調用wait、notify和notifyAll的對象是

                  同一個對象,也就是都是this鎖代表的對象。

                格式:

                synchronized(對象)

                {

                        需同步的代碼;

                }

        (2)同步函數

                同步方法是指進入該方法時需要擷取this對象的同步鎖,在方法上使用synchronized關鍵字,

                使用this對象作為鎖,也就是使用了目前對象,因為鎖住了方法,是以相對于代碼塊來說效率相對較低。

                注:靜态同步函數的鎖是該方法所在的類的位元組碼檔案對象,即類名.class檔案

                格式:

                修飾詞 synchronized 傳回值類型 函數名(參數清單)

                {

                        需同步的代碼;

                }

        在jdk1.5後,用lock鎖取代了synchronized,個人了解也就是對同步代碼塊做了修改,

        并沒有提供對同步方法的修改,主要還是效率問題吧。

《JAVA大學簡明教程:執行個體程式設計》電子版免費下載下傳

【百度網盤分享】Java基礎總結

繼續閱讀