您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么創建Java線程對象”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
默認情況下,主線程和垃圾回收線程都是由系統創建的,但是我們需要完成自己的功能----創建自己的線程對象
java將線程面向對象了,形成的類就是Thread,在Thread類內部執行任務的方法叫run()
注意:如果想讓run作為任務區,必須讓他去被自動調用.我們通過執行start()方法,來開啟線程,繼而實現run方法的自動調用.
主線程的名字:main 子線程的名字:從Thread-0開始命名
//創建自己的線程對象
//分析:由于我們實現的實際功能Thread類是決定不了的,所以沒有辦法將我們的功能放入Thread的run方法里,如果我們想實現自己的功能,可以寫Thread類的子類,重寫run方法,實現我們的功能.run就是我們的任務區
實現多線程的方式兩種:
第一種方式:通過創建Thread子類的方式實現功能----線程與任務綁定在了一起,操作不方便
第二種:將任務從線程中分離出來,哪個線程需要工作,就將任務交給誰,操作方便
當線程與任務分離后
這里Thread內部默認有一個run,又通過ticket傳入一個run,為什么優先調用的是傳入的run
如果該線程是使用獨立的 Runnable 運行對象構造的,則調用該 Runnable 對象的 run 方法;否則,該方法不執行任何操作并返回。
2.線程安全
1、synchronized關鍵字:
1、synchronized關鍵字的作用域有二種:
1)是某個對象實例內,synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;
2)是某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。
2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用于方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/區塊/},它的作用域是當前對象;
3、synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中并不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;
實現線程安全的方式:
1.在代碼中使用同步代碼塊兒(同步鎖)
解釋:在某一段任務中,同一時間只允許一個線程執行任務,其他的線程即使搶到了cpu,也無法進入當前的任務區間,只有當當前的線程將任務執行完后,其他的線程才能有資格進入
同步代碼塊兒的構成:
synchronized(鎖(對象)){
同步的代碼
}
對作為鎖的對象的要求:
1.必須是對象
2.必須保證被多個線程共享
可以充當鎖的:
1.一個普通的對象
2.當前對象的引用--this
3.類的字節碼文件 --注意:字節碼文件的使用范圍太大,一般不建議使用.
同步代碼塊兒的特點:
1.可以保證線程的安全
2.由于每次都要進行判斷處理,所以降低了執行效率
總結:什么時候使用同步代碼塊兒
1.多個線程共享一個數據
2.至少有兩個線程
比較同步代碼塊兒和同步函數
同步代碼塊兒使用更加的靈活,只給需要同步的部分代碼同步即可,而同步函數是給這個函數內的所有代碼同步.
由于處于同步的代碼越少越好,所以最好使用同步代碼塊兒
注意:1.當在一個類中同時存在多個synchronized修飾的代碼塊兒或函數時,要想安全,就必須讓他們后面的對象一致。因為只有同一把鎖才能安全。
同步函數的鎖:this
2靜態同步函數在進內存的時候不會創建對象,但是存在其所屬類的字節碼文件對象,屬于class類型的對象,
所以靜態同步函數的鎖是其所屬類的字節碼文件對象
示例:
//使用同步代碼塊兒
public void addMoney(int money) {
synchronized (Bank.class) {
this.money += money;
System.out.println(this.money);
}
}
//使用同步函數
//非靜態的同步函數
//在synchronized后面默認有一個this
public synchronized void addMoney(int money) {
this.money += money;
System.out.println(this.money);
}
wait():讓當前的線程變成等待的狀態,放入一個池子(線程容器),失去了搶cpu的能力,.等待喚醒(鎖相當于給當前的線程做了一個標記)
notify():讓當前的線程從等待狀態喚醒,相當于從池子中取出線程.(喚醒的是同一把鎖下的任意一個線程)
notifyAll():喚醒的是同一把鎖下的所有線程
死鎖:出現的情況有兩種
1.所有的線程處于等待狀態
2.鎖之間進行嵌套調用
2.Lock
比較synchronized和Lock
1.synchronized:從jdk1.0就開始使用的同步方法-稱為隱式同步
synchronized(鎖對象){//獲取鎖 我們將鎖還可以稱為鎖旗艦或者監聽器
同步的代碼
}//釋放鎖
2.Lock:從jdk1.5開始使用的同步方法-稱為顯示同步
原理:Lock本身是接口,要通過他的子類創建對象干活兒
使用過程:
首先調用lock()方法獲取鎖
進行同步的代碼塊兒
使用unlock()方法釋放鎖
使用的場景:
當進行多生產者多消費者的功能時,使用Lock,其他的都使用synchronized
使用效率上:Lock高于synchronized
線程的停止: 3種
1.通過一個標識結束線程
2.調用stop方法---因為有固有的安全問題,所以系統不建議使用.
3.調用interrupt方法----如果目標線程等待很長時間(例如基于一個條件變量),則應使用 interrupt 方法來中斷該等待。
守護線程:
相當于后臺線程.依賴于前臺線程.正常情況下,當前臺線程結束的時候,不管守護線程有沒有結束,都會立刻結束.
典型的守護線程:垃圾回收線程
當程序調用setDaemon方法時,并且將參數設置成true.當前線程就變成了守護線層.
注意:這個方法一定要在start方法之前調用
thread0.setDaemon(true);
thread0.start();
join()方法:
原理:線程一旦調用了join方法,他的優先級會高于主線程.主線程會等當前的線程執行完后再去執行.
注意點:優先級只比main線程的高.對其他的線程沒有影響.
當線程開始工作后,讓t0調用join方法,讓他的優先級高于main線程
注意:join方法必須在線程開始工作后,執行.
t0.start(); try { t0.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }
wait():使一個線程處于等待狀態,并且釋放所持有的對象的lock。
sleep():使一個正在運行的線程處于睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處于等待狀態的線程,注意的是在調用此方法的時候,并不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
notityAll():喚醒所有處入等待狀態的線程,注意并不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
“怎么創建Java線程對象”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。