第十五天(多线程-部分)

      這塊中線程同步有點難理解,有些理解有些不,懶得寫了,轉載他人的文章充數吧。

2011-06-09(Multi-thread)
1、線程有二含義,一是一條獨立的執行線索,二是java.lang.Thread類或其子類。java中開發線程有兩種方法:繼承Thread類和實現Runnable接口。
I、繼承Thread類。直接或間接,重寫run方法。run方法中的代碼就是線程所要執行任務:
                           class <類名> extends Thread{
                                  public void run(){
                                 //...
                                 }
                            }
run方法必須要要這樣寫才能有成為一條獨立線索的能力,其他的重載run方法,調用run會喪失此功能。創建線程對象時,繼承了Thread的類的對象本身就是線程對象,可以使用與別的一般類的方法來創建線程對象:
                                   Thread t=new <繼承Thread的類的構造器>;
II、實現Runnable接口。應用繼承Thread的方法來開發線程有個不好之處:所開發的線程不能繼承其他類。所以java提供了另一種方法來開發線程:通過實現Runnable接口來重寫run方法。這裡,實現Runnable的類只是通過實現run方法指出線程需要完成的任務,而想得到一個線程必須創建Thread的或其子類的對象,所以這個類的對象不是一個線程。所以想創建線程對象,就要Thread的構造器來完成(一部份的構造方法):
                                               
public Thread(Runnable target)
比如類A實現了Runnable接口,所以創建線程對象時,要:
                                                    A a=new A();
                                                   Thread t=new Thread(a);
當然,A的同一個對象可以重複傳遞給多個線程對象,只是意味著這個幾個線程對象啟動后將執行完全相同的任務。另外,Thread本身也實現了Runnable接口,因此Thread或其子類的對象可作為參數傳遞給新的線程對象。
2、啟動線程。創建線程對象后,在沒有啟動它之前還是一個普通的對象。這時可以調用線程中可見的方法,包括run方法。雖然表面上是運行了run方法,但這個還是單線程,即仍然是在main這條主線程中執行了run,而非單獨開了一條線程來運行run中的代碼。想要啟動一個線程開闢一個線程,只需調用線程對象的start方法。另外線程在器其生命週期只能別調用一起,如果在線程啟動后再起啟動會拋出異常,這個異常是:IllegalThreadException。
3、多個線程的運行。如果多個線程沒有同步約束關係,則無法保證那個線程先執行及其持續時間,只能保證的是:每個線程都將啟動,每個線程都會執行結束。比如線程A、B,如果AB之間沒有邏輯的約束,則java不能保證A、B執行先後,也不能保證執行時間。唯一可以保證的是,A、B都會執行完。
4、線程狀態。
I、新建狀態:對象創建后即,未被啟動之前,為新建狀態;
II、準備狀態:線程對象被調用了start方法后就進入了準備狀態,此時根據實際狀況,準備狀態的線程隨時有可能被調度。一旦進入此狀態就不能再回到新建狀態了;
III、運行狀態:獲得必要的條件后,就會進入運行狀態,在此狀態下,線程隨時有可能被調度會準備狀態。運行過程中,由於需要某些必要的條件,或者運行了某些特定的方法,會使之進入等待或阻塞狀態;
IV、等待、阻塞狀態:由於某些原因線程不能繼續執行,原因包括:睡眠、阻塞、掛起、等待。
(1)睡眠。被調用了sleep方法,進入睡眠狀態;
(2)阻塞。調用了阻塞方法,而正好滿足了阻塞的條件,就會進入此狀態;
(3)掛起。調用了suspend方法會掛起,直至調用resume方法才回到狀態。但使用suspend方法很容易引發線程的死鎖,不應使用。
(4)等待。正在運行的線程由於邏輯條件不滿足,自動調用wait方法進入等待狀態。
V、死亡狀態。由於線程執行完畢或由於發生異常而終止執行是,會進入死亡狀態。
5、睡眠。調用sleep可使線程睡眠指定的一段時間,此為線程讓出CPU的最簡單方法之一。
                      public static sleep(long millis)throws InterruptedException
                      public static sleep(long millis ,int nanos)throws InterruptedException
①第二個方法nanos為指定的額外等待的納秒數,注意這個納秒計時是不太準確。

②兩個方法均為靜態方法,在哪個線程中使用哪個線程就睡眠。

③睡眠后隨即進入準備狀態,並不能保證立即執行,因此,指定的睡眠時間為線程暫停的最小時間。
6、優先調節。java的優先級別調劑策略:優先度高的線程有更大的獲取CPU資源而執行的概率,優先度第的線程並不是總不執行。這是個概率問題,只能適用於線程的宏觀調控。
優先級用1-10之間的整數表示,數值越大,優先度越高。一般地,默認為5,主線程優先度為5。對於子線程,其初始優先度與父線程一樣。若要改變線程優先度,用:
public final void setPriority(int newPriority)
方法為final,說明不能重寫;newPriority為1到10之間的整數。有時爲了便於記憶,使用3個常量來表示優先級:Thread.MAX_PRIORITY(最高優先級)、Thread.NORM_PRIORITY(默認優先級)、Thread.MIN_PRIORITY(最低優先級)
7、線程讓步。線程讓步有兩種方法yield()和join()
I、yield()。調用yield會使正在運行的線程然出CPU,回到準備狀態,注意是裝備狀態,很可能是回到準備狀態后又被調度進入運行狀態,就是說,有可能讓步不成功。yield()方法:
                                                     public static void yield();
與sleep方法一樣,為靜態方法,哪個線程調用,哪個線程就讓出CUP。
II、join()。
                        public final void join()throws InterruptedException
                        public final void join(long millis))throws InterruptedException
                        public final void join(long millis ,int nanos)throws InterruptedException
這個是非靜態最終方法:由線程對象調用,不能重寫。調用join方法的線程會加入到當前運行的線程中,起到讓步的作用。調用無參join方法,表示加入時間一直持續到調用的線程執行完畢,讓步的線程才能恢復執行,效果上是兩個線程合併稱一個線程。調用有參的,加入時間是指定的時間。
8、守護線程(Deamon)。守護線程是線程的一種,可以為非守護線程提供很多輔助功能。當JVM中只剩下守護線程時,JVM就會停止工作。可用setDeamon方法將某個線程設置為守護線程:
                                    public final void setDeamon(boolean on)
參數on為true時,將其設置為守護線程;反之為前臺(用戶)線程。
9、線程同步。表示無力,不完全理解。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值