進程:就是正在運行的程序,分配內存讓應用程序可以運行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方法必須有鎖對象來調用