進程
概念
進程是指一個內存中運行的應用程序,每個進程都有自己獨立的一塊內存空間,一個進程中可以啓動多個線程。比如在windows系統中,一個運行的exe就是一個進程。
線程
線程是指進程中的一個執行流程,一個進程中可以運行多個線程。比如java.exe進程中可以運行很多線程。線程總是屬於某個進程,進程中的多個線程共享進行的內存。“同時執行”是人的感覺,其實是線程之間實際上輪換執行。
線程實現
定義線程
線程有兩種方式
1. 擴展java.lang.Thread類
2. 實現java.lang.Runable接口
實例化線程
1. 如果是擴展java.lang.Thread類的線程,則直接new即可。
2. 如果是實現了java.lang.Runable類的接口,則用Thread的構造方法:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name,long stackSize)
啓動線程
在線程的Thread對象上調用start()方法,而不是run()或者別的方法。
在調用start()之前:線程處於新狀態中,新狀態指有一個Thread對象,但是還沒有一個真正的線程。在調用start()方法之後:發生了一些列複雜的事情,該線程從新狀態轉移到可運行狀態;當線程獲得機會執行時,其目標Run()方法運行
注意:對java來說,run()方法沒有任何特別之處。就像main()方法一樣,它只是新線程知道調用的方法名稱(和簽名)。因此,在Runable上或者Thread上調用run方法時合法的。但是並不啓動新的線程。
線程的狀態
新狀態(new)
線程對象已經創建,還沒有在其上調用start()方法
可運行狀態(Runnable)
當線程有資格運行,但調度程序還沒有把它選定爲運行線程時所處的狀態。當start()方法調用時,線程首先進入可運行狀態。在線程運行之後或者從阻塞、等待或者睡眠狀態回來,也可返回到可運行狀態。
運行狀態(Running)
線程調度程序從可運行池中選擇一個線程作爲當前線程時所處的狀態。這也是線程進入運行狀態的唯一一種方式。
等待/阻塞/睡眠狀態(Watiing/Timed_waiting/Blocked)
這是線程有資格運行時它所處的狀態。實際上這個三狀態組合爲一種,共同點是:線程仍舊是獲得,但是當前沒有條件運行。換句話說,他是可運行的,如果某件事件出現,他可能返回到可運行狀態。
死亡態(terminated)
當線程的run()方法完成時就認爲它死去。這個線程對象也許是活的,但是,它已經不是一個單獨執行的線程。線程一旦死亡,就不能復生。如果在一個死去的線程上調用start()方法,會拋出java.lang.IllegalThreadStateException異常。線程同步
線程的同步是爲了防止多個線程訪問一個數據對象時,對數據造成的破壞。
鎖的原理
Java中每個對象都有一個內置鎖
當程序運行到非靜態的synchronized同步方法上時,自動獲得與正在執行代碼類的當前實例(this實例)有關的鎖。獲得一個對象的鎖也稱爲獲取鎖,鎖定對象,在對象上鎖定或在對象上同步。
當程序運行到synchronized同步方法或代碼塊時,該對象鎖才起作用。
一個對象只有一個鎖。所以,如果一個線程獲得該所,就沒有其他線程可以獲得鎖,知道第一個線程釋放鎖。這也意味着人戶其他線程都不能進入該對象上的synchronized方法或代碼塊,知道該鎖被釋放。
釋放鎖是指:持鎖線程退出了synchronized同步方法或代碼塊。
關於鎖和同步,由一下幾個要點
1. 只能同步方法,不能同步變量和類;
2. 每個對象只有一個鎖;當提到同步時,應該清楚在什麼上同步?也就是說在哪個對象上同步。
3. 如果兩個線程要執行一個類中的synchronized方法,並且兩個線程使用相同的實例來調用方法,那麼一次只能有一個線程能夠執行方法,另一個需要等待,知道鎖被釋放。也就是說:如果一個線程在對象上獲得一個鎖,就沒有任何其他線程進入(該對象)類中的任何一個同步方法。
4. 線程睡眠時,它所持的任何鎖都不會釋放。
5. 同步損害併發性,所以應該儘可能縮小同步範圍。同步不但可以同步整個方法,還可以同步方法中一部分代碼塊。
6. 在是用同步代碼塊時候,應該指定在哪個對象上同步,也就是說要獲取哪個對象的鎖。
舉例:用多線程模擬3個窗口售賣火車票
當一個類已經很好的同步以保護它的數據時,這個類就被稱爲“線程安全的”。