Thread部分解釋總結筆記

Thread實現了接口Runnable,該接口只有一個run()方法,
  使用實現接口 Runnable 的對象創建一個線程時,啓動該線程將導致在獨立執行的線程中調用對象的 run 方法。
使用實現接口 Runnable 的對象創建一個線程時,啓動該線程將導致在獨立執行的線程中調用對象的 run 方法。
方法 run 的常規協定是,它可能執行任何所需的動作。


..........................................................................................................

Thread繼承了Object和Interface Runnable
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
創建新執行線程有兩種方法。
............................................................................................................
一種方法是將類聲明爲 Thread 的子類。該子類應重寫 Thread 類的 run 方法。
接下來可以分配並啓動該子類的實例
............................................................................................................
class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }
 ......................................................................
然後,下列代碼會創建並啓動一個線程:


     PrimeThread p = new PrimeThread(143);
     p.start();
............................................................................
創建線程的另一種方法是聲明實現 Runnable 接口的類。該類然後實現 run 方法。
然後可以分配該類的實例,在創建 Thread 時作爲一個參數來傳遞並啓動。
採用這種風格的同一個例子如下所示:
.............................................................................................
class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }
 
         public void run() {
             // compute primes larger than minPrime
              . . .
         }
......................................................................................................
然後,下列代碼會創建並啓動一個線程:


     PrimeRun p = new PrimeRun(143);
     new Thread(p).start();
..........................................................................................................
 每個線程都有一個標識名,多個線程可以同名。如果線程創建時沒有指定標識名,就會爲其生成一個新名稱。
..........................................................................................................
啓動start()方法,必須是Thread的實例。


...........................................................................................................
接口中可以定義方法和常量,但是不能定義變量。

...........................................................................................................
join()等待該線程終止
..............................................................................
用wait()和notify()方法,可以實現線程之間的交互。wait()是該線程的處於等待狀態,notify()是喚醒不工作的線程。
在本線程內,可以設置自己的狀態爲wait(),喚醒別的線程用notify()
其中,notify()和notifyAll()的區別是前者是喚醒在此對象監視器上等待的單個線程,後者是喚醒在此對象監視器上等待的所有線程。
.........................................................................................................
在Java中,線程是搶佔式的,不是分時的。
搶佔式的調度模型是指可能多個線程是可以運行的,但是隻有一個線程得逞。直到該線程不再運行。一個線程不再運行的原因有好多種。

線程的代碼可能執行了一個Thread.sleep()調用,要求這個線程暫停一段固定的時間。這個線程可能在等待訪問某個資源,而這個資源可訪問之前,
這個線程無法繼續運行。
.......................................................................
因爲Java線程不一定是分時的,所以你必須確保你的代碼中的線程會不時的給另外一個
線程運行的機會。這可以通過在各種時間間隔中發出sleep()調用來做到。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Thread.sleep()和其它使線程暫停一段時間的方法是可以中斷的。
線程可以調用另外一個線程的interrupt() 方法, 這將向暫停的線程發出一個
InterruptedException。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
注意Thread類的sleep()方法對當前線程的操作。除非線程因爲中斷而提早回覆執行,否則它不會在這段時間之前回復執行。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Thread類的另一個方法yield(),可以用來使具有相同優先級的線程獲得執行的機會。
如果具有相同優先級的其它線程是可運行的,yield()將把調用線程放到可運行池中
並使另一個線程運行。如果沒有相同優先級的線程,yield()什麼都不做。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
注意:sleep()調用會給較低優先級線程一個運行的機會。yield()方法只會給相同
優先級線程一個執行的機會。
.......................................................................
有時線程可處於一個未知的狀態。isAlive()方法用來確定一個線程是否是活的。
活着的線程並不意味着線程正在運行;對於一個一開始運行但還沒有完成任務的線程,
這個方法返回true
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
延遲線程:

sleep()
該方法是使線程停止一段時間的方法。在sleep時間間隔期滿後,線程不一定立即恢復執行。
這是因爲在那個時刻,其它線程可能正在運行而且,沒有被調度爲放棄執行,除非:
1、“醒來”的線程具有更高的優先級
2、正在運行的線程因爲其它原因而阻塞。
...................................................................
join()
該方法使當前線程停下來等待,直至另一個調用join方法的線程終止。void join (long timeout);
其中 join()方法會掛起當前線程。掛起的時間或者爲timeout 毫秒,或者掛起當前線程直
至它所調用的線程終止。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
下面介紹一下用哪種方法生成線程。
第一種:實現Runnable接口
更符合面向對象的設計;單繼承;一致性;

第二種方法:擴展Thread
代碼更簡單。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
實現Runnable的優點:
1、從面向對象的角度來看,Thread類是一個虛擬處理機嚴格的封裝,因此只有當處理機模型修改或擴展時,纔可以繼承類。

正因爲這個原因和區別一個正在運行的線程的處理機、代碼和數據部分的意義。

2、由於Java技術只允許單一繼承,所以如果你已經繼承了Thread,你就不能再繼承其它任何類了。
在某些情況下,這會使你只能採用實現Runnable的方法。
3、因爲有時你必須實現Runnable,所以你可能喜歡保持一致,並總是使用這種方法。


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
繼承Thread的優點:
1、當一個run()方法體現在繼承Thread類的類中,用this指向實際控制運行的Thread
實例。因此,代碼不再需要使用如下控制:
Thread.currentThread().join();
而可以簡單地用:
join();
因爲代碼簡單了一些,許多Java編程語言的程序員使用擴展Thread機制。注意:如果你採用這種
方法,在你的代碼生命週期的後期,單繼承模型可能會給你帶來困難。
。。。。。。。。.......................................................


使用Java 技術中的synchronized:
.......................................................................

1、每個對象都有一個標誌,它可以被認爲是“鎖標誌”
2、synchronized允許和鎖標誌交互。即允許獨佔地存取對象。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
當線程運行到synchronized語句,它檢查作爲參數傳遞的對象,並在繼續執行之前
試圖從對象獲得鎖標誌。
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
當線程運行到synchronized語句,它檢查作爲參數傳遞的對象,並在繼續執行
之前試圖從對象獲得鎖標誌。
.....................................................................


釋放鎖標誌:線程執行到synchronized代碼塊末尾時釋放。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


synchronized----放在一起
所有對易碎數據的存取應當同步。
由synchronized保護的易碎數據應當是private的。
正如所暗示的那樣,只有當所有對易碎數據的存取位於同步塊內,synchronized()
纔會發生作用。
所有由synchronized塊保護的易碎數據應當標記爲private。

考慮來自對象的易碎部分的
數據的可存取性。如果它們不被標記爲private,則它們可以由位於類定義之外的代碼存取。
這樣,你必須確信其他程序員不會省略必需的保護。
一個方法,如果它全部屬於與這個實例同步的塊,它可以把 synchronized 關鍵字放到它
的頭部。(意思是執行方法的過程當中當前對象被鎖定)下面兩段代碼是等價的:
public void push(char c) {
synchronized(this) {
:
:
}
}
public synchronized void push(char c) {
:
:
}
////////////////////////////////////////////////////////////////////


main方法是主線程。

進程是靜態的。

。。。。。。。。。。。。。。。。。。。。。。。。。

在非線程的class中定義的方法,中調用this.wait()方法,意思是停止當前線程。其方法在java.Lang.Object包中。一旦wait過去,對象的鎖,不再擁有,而sleep時,還抱着鎖。wait過去的,自己不能醒來,必須喚醒。notify()主要是叫醒一個處在wait()狀態的線程。
。。。。。。。。。。。。。。。。。。。。。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章