Thread 线程同步、线程状态
線程概念
線程(英語:thread)是操作系統(tǒng)能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。
一、多線程介紹
1.1創(chuàng)建線程類
Java中通過繼承Thread類來創(chuàng)建并啟動多線程的步驟如下:
1.定義Thread類的子類,并重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務,因此把run()方法稱為線程執(zhí)行體。
2. 創(chuàng)建Thread子類的實例,即創(chuàng)建了線程對象
3. 調用線程對象的start()方法來啟動該線程
測試類:
public class ThreadIdea {
public static void main(String[] args) {
subThread th=new subThread();
th.start();
for (int i = 0; i < 200; i++) {
System.out.println(Thread.currentThread().getName()+" 主線程被執(zhí)行"+i+“次”);
}
}
}
自定義線程類:
public class subThread extends Thread{
@Override
public void run() {//重寫run方法
for (int i = 0; i < 200; i++) {
System.out.println(Thread.currentThread().getName()+" 子線程被執(zhí)行"+i+“次”);
}
}
}
二、多線程的原理
2.1多線程的原理
代碼同上
2.2Thread類
操作過程中用到了java.lang.Thread類
1.構造方法:
public Thread():分配一個新的線程對象。
public Thread(String name):分配一個指定名字的新的線程對象。
public Thread(Runnable target):分配一個帶有指定目標新的線程對象。
public Thread(Runnable target,String name):分配一個帶有指定目標新的線程對象并指定名字。
2常用方法:
public String getName():獲取當前線程名稱。
public void start():導致此線程開始執(zhí)行; Java虛擬機調用此線程的run方法。
public void run():此線程要執(zhí)行的任務在此處定義代碼。
public static void sleep(long millis):使當前正在執(zhí)行的線程以指定的毫秒數(shù)暫停(暫時停止執(zhí)行)。
public static Thread currentThread():返回對當前正在執(zhí)行的線程對象的引用。
翻閱API后得知創(chuàng)建線程的方式總共有兩種,一種是繼承Thread類方式,一種是實現(xiàn)Runnable接口方式,方式一我們上一天已經完成,接下來講解方式二實現(xiàn)的方式。
2.3 實現(xiàn)接口方式
采用java.lang.Runnable也是非常常見的一種,我們只需要重寫run方法即可。
步驟如下:
1.定義Runnable接口的實現(xiàn)類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執(zhí)行體。
2.創(chuàng)建Runnable實現(xiàn)類的實例,并以此實例作為Thread的target來創(chuàng)建Thread對象,該Thread對象才是真正的線程對象。
3.調用線程對象的start()方法來啟動線程。代碼如下:
測試類代碼:
public class test {
public static void main(String[] args) {
runnable runa=new runnable();
Thread th=new Thread(runa);
th.start();
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName()+" 主線程被調用");
}
}
}
Runnable接口代碼:
public class runnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName()+" 子線程被調用"+i);
}
}
}
通過實現(xiàn)Runnable接口,使得該類有了多線程類的特征。run()方法是多線程程序的一個執(zhí)行目標。所有的多線程代碼都在run方法里面。Thread類實際上也是實現(xiàn)了Runnable接口的類。
在啟動的多線程的時候,需要先通過Thread類的構造方法Thread(Runnable target) 構造出對象,然后調用Thread對象的start()方法來運行多線程代碼。//代碼中沒體現(xiàn)構造Thread這一點
實際上所有的多線程代碼都是通過運行Thread的start()方法來運行的。因此,不管是繼承Thread類還是實現(xiàn)Runnable接口來實現(xiàn)多線程,最終還是通過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程編程的基礎。
Thread和Runnable的區(qū)別
如果一個類繼承Thread,則不適合資源共享。但是如果實現(xiàn)了Runable接口的話,則很容易的實現(xiàn)資源共享。
總結:
實現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:
1.適合多個相同的程序代碼的線程去共享同一個資源。
2.可以避免java中的單繼承的局限性。
3.增加程序的健壯性,實現(xiàn)解耦操作,代碼可以被多個線程共享,代碼和線程獨立。
4.線程池只能放入實現(xiàn)Runable或Callable類線程,不能直接放入繼承Thread的類。
2.4 匿名內部類方式
使用匿名內部類的方式實現(xiàn)Runnable接口,重新Runnable接口中的run方法:
public class anonymousInsideClass {
public static void main(String[] args) {
new Thread(new runnable(){
@Override
public void run() {
System.out.println(“使用匿名內部類線程”);
}
}).start();
//相當于
Thread th= new Thread();
runnable runmethond=new runnable(){
@Override
public void run() {
System.out.println(“使用匿名內部類線程”);
}
};
new Thread(runmethond).start();
}
}
三、線程安全
3.1 線程安全
3.2 線程同步
當我們使用多個線程訪問同一資源的時候,且多個線程中對資源有寫的操作,就容易出現(xiàn)線程安全問題。要解決上述多線程并發(fā)訪問一個資源的安全性問題:也就是解決重復票與不存在票問題,Java中提供了同步機制(synchronized)來解決。
為了保證每個線程都能正常執(zhí)行原子操作,Java引入了線程同步機制。那么怎么去使用呢?有三種方式完成同步操作:
同步代碼塊。同步方法。鎖機制。
3.3 同步代碼塊
同步代碼塊:synchronized關鍵字可以用于方法中的某個區(qū)塊中,表示只對這個區(qū)塊的資源實行互斥訪問。
格式:
synchronized(同步鎖){
需要同步操作的代碼
}
同步鎖:
對象的同步鎖只是一個概念,可以想象為在對象上標記了一個鎖.
鎖對象 可以是任意類型。
多個線程對象 要使用同一把鎖。
同步方法
同步方法:使用synchronized修飾的方法,就叫做同步方法,保證A線程執(zhí)行該方法的時候,其他線程只能在方法外等著。
3.5 Lock鎖
java.util.concurrent.locks.Lock機制提供了比synchronized代碼塊和synchronized方法更廣泛的鎖定操作,同步代碼塊/同步方法具有的功能Lock都有,除此之外更強大,更體現(xiàn)面向對象。
Lock鎖也稱同步鎖,加鎖與釋放鎖方法化了,如下:
public void lock():加同步鎖。
public void unlock():釋放同步鎖。
四、線程的狀態(tài)
NEW(新建)
線程剛被創(chuàng)建,但是并未啟動。還沒調用start方法。Runnable(可運行)線程可以在java虛擬機中運行的狀態(tài),可能正在運行自己代碼,也可能沒有,這取決于操作系統(tǒng)處理器。
Blocked(鎖阻塞)
當一個線程試圖獲取一個對象鎖,而該對象鎖被其他的線程持有,則該線程進入Blocked狀態(tài);當該線程持有鎖時,該線程將變成Runnable狀態(tài)。
Waiting(無限等待)
一個線程在等待另一個線程執(zhí)行一個(喚醒)動作時,該線程進入Waiting狀態(tài)。進入這個狀態(tài)后是不能自動喚醒的,必須等待另一個線程調用notify或者notifyAll方法才能夠喚醒。
Timed Waiting(計時等待)
同waiting狀態(tài),有幾個方法有超時參數(shù),調用他們將進入Timed Waiting狀態(tài)。這一狀態(tài)將一直保持到超時期滿或者接收到喚醒通知。帶有超時參數(shù)的常用方法有Thread.sleep 、Object.wait。
Teminated(被終止)
因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。
總結
以上是生活随笔為你收集整理的Thread 线程同步、线程状态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos软件免费(ddos软件vip版)
- 下一篇: File类、递归、字节流