關於java線程的一些瞭解

                      

進程:就是正在運行的程序,分配內存讓應用程序可以運行html

Windows系統號稱多任務(能夠同時運行多個應用程序)java

   宏觀上看:windows確實是容許多個程序windows

   微觀上看:CPU快速切換執行任務,因爲速度特別快,咱們人感受不到這個切換的過程安全

 

線程:線程在一個進程中負責代碼的執行,就是一個進程中的執行路徑多線程

 疑問:沒有學習線程,爲何代碼能夠執行jvm

      Java程序在運行的時候,jvm會幫咱們建立一個主線程來執行代碼。主線程主要負責main方法中的代碼執行函數

一個java程序中至少有2個線程:學習

一個是主線程主要負責main方法中的代碼執行,一個垃圾回收站線程,負責垃圾回收this

 

多線程:在一個進程中多個線程同時執行不一樣的任務。「同時」:單核CPU快速切換多線程執行任務,速度特別快,感受不到切換spa

多線程的好處:

1.解決一個進程中同時執行多個任務的問題

2.提升資源的利用率

多線程的弊端:

1.增長CPU的負擔,不是線程越多越好

2.下降了一個進程中線程的執行機率

3.線程容易引起線程安全問題

4.容易出現死鎖現象

 

Java中建立線程的兩種方式:
 方式一:Thread(線程類)

       1.須要定義一個類來繼承Thread類

       2.重寫thread類中的run方法,把自定義線程的任務代碼寫在run方法中

    每個線程都會有本身的任務代碼,jvm建立的主線程的任務代碼就是main方法,自定義的線程的任務代碼就寫在run方法中

       3.建立Thread的子類,而且調用start方法開啓線程

  注意點:一旦線程開啓了,會默認執行線程對象中的run方法,可是千萬不要本身直接調用run方法,若是直接調用run方法就和普通方法沒什麼區別

 

   線程的生命週期:

建立:新建立了一個線程對象。

可運行:線程對象建立後,其餘線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取cpu的執行權。

運行:就緒狀態的線程獲取了CPU執行權,執行程序代碼。

阻臨時塞: 阻塞狀態是線程由於某種緣由放棄CPU使用權,暫時中止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。

死亡:線程執行完它的任務時。

 

  線程中經常使用的方法:

     Thread(String name)  初始線程的名字

     getNema()            返回線程的名字

     setNema(String name) 設置線程對象名

     Sleep()              線程睡眠的指定毫秒數

     getPriority()返回當前對象的優先級  默認線程的優先級是5

     setPriority(int newPriority) 設置線程的優先級 雖然設置可優先級,可是具體的實現取決於底層的操做系統的實現 (優先級最大的是 10,最小的是1,默認的是5)

currentThread()       返回CUP正在執行的線程的對象

 

對於線程不安全的解決方法:
  java給線程加鎖:

   方式一:同步代碼塊

 鎖對象能夠是任意一個java中的對象(任意類型的對象)

 Java中的任意一個對象都會有一個對象的狀態,就能夠經過對象的狀態做爲鎖的一個標識符   

列如:  statue = 0 表示鎖關閉  statue=1表示打開

 Synchronized(鎖對象){   }

 

同步代碼塊的使用注意點:

      1.任意一個對象均可以作鎖對象

      2.若是你在同步代碼塊中調用了sleep方法,不會釋放鎖對象

      3.只有正真的存在線程安全的時候才須要使用同步代碼塊,

不然會下降執行效率

      4.多線程操做鎖對象必須是惟一,不然無效

不知道線程何時安全何時不安全?

 

  出現線程安全的問題根本緣由:

    1.存在兩個或者兩個以上的線程,而且線程之間共享着一個資源

2.多個語句操做共享資源

 方式二:同步函數:用關鍵字synchronized 修飾函數

   同步函數是有鎖對象的
  同步函數的使用是一個靜態函數注意點:

      1.如是一個非靜態的函數,同步函數的鎖就是調用方法的對象(this對象),若是是一個靜態同步函數的鎖對象是當前函數所屬類的字節碼文件(class對象)

      2.同步函數的鎖對象是固定的,不可以本身指定

      3.同步函數是同步整個函數的代碼

同步代碼塊和同步函數中,優先使用同步代碼塊     

     緣由:

     1.同步代碼塊的鎖對象能夠由我任意指定,同步函數是固定的

     2.同步代碼塊能夠控制被同步範圍,同步函數必須是整個函數的全部代碼都被同步

線程死鎖現象問題:

線程死鎖不必定會出現,有可能會出現

死鎖現象的解決方法:沒有方案,儘可能避免

 

線程的定義方式二:

     1.自定義一個實現Runable接口,接口中會提供一個run方法

 2.實現Runable接口中的run方法,將線程中的任務寫在run方法中

     3.建立Runable接口的實現對象

     4.建立一個Thread對象,而且把Runable實現類建立的對象做爲參數

     5.調用Tread對象的star方法來開啓線程

 

問題:爲何要將Runable接口實現類的對象做爲參數傳遞?

   爲了讓對象中的run方法可以在線程中的run方法中執行,也就是可以將這個對象中的run方法做爲線程中的任務來執行

方法Thread和Runable 推薦使用Runable

Java是單繼承,就不可以繼承Thread對象來實現多線程

 

線程的通信:一個線程完成本身的任務,去通知另一個線程去完成另外一個任務

 wait();  等待 若是線程執行了wait方法,那麼該線程就會處於一個等待狀態,等待狀態的線程必需要經過其餘線程來調用notify()方法來喚醒

 notify(); 喚醒  隨機喚醒線程池中的一個線程

 notifyAll();喚醒全部的線程

 

wait和notify的使用注意點:

1.wait方法和notify方法是屬於Object對象

2.wait方法和notify方法必須在同步線程中執行

3.wait方法和notify方法必須有鎖對象來調用

相關文章
相關標籤/搜索