程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 多線程設計要點

多線程設計要點

編輯:JAVA編程入門知識

  1.多線程中有主內存和工作內存之分, 在JVM中,有一個主內存,專門負責所有線程共享數據;而每個線程都有他自己私有的工作內存, 主內存和工作內存分貝在JVM的stack區和heap區。
  
  2.線程的狀態有'Ready', 'Running', 'Sleeping', 'Blocked', 和 'Waiting'幾個狀態,
  
  'Ready' 表示線程正在等待CPU分配答應運行的時間。
  
  3.線程運行次序並不是按照我們創建他們時的順序來運行的,CPU處理線程的順序是不確定的,假如需要確定,那麼必須手工介入,使用setPriority()方法設置優先級。
  
  4.我們無從知道一個線程什麼時候運行,兩個或多個線程在訪問同一個資源時,需要synchronized
  
  5. 每個線程會注冊自己,實際某處存在著對它的引用,因此,垃圾回收機制對它就“束手無策”了。
  
  6. Daemon線程區別一般線程之處是:主程序一旦結束,Daemon線程就會結束。
  
  7. 一個對象中的所有synchronized方法都共享一把鎖,這把鎖能夠防止多個方法對通用內存同時進行的寫操作。synchronized static方法可在一個類范圍內被相互間鎖定起來。
  
  8. 對於訪問某個要害共享資源的所有方法,都必須把它們設為synchronized,否則就不能正常工作。
  
  9. 假設已知一個方法不會造成沖突,最明智的方法是不要使用synchronized,能提高些性能。
  
  10. 假如一個"同步"方法修改了一個變量,而我們的方法要用到這個變量(可能是只讀),最好將自己的這個方法也設為 synchronized。
  
  11. synchronized不能繼續, 父類的方法是synchronized,那麼其子類重載方法中就不會繼續“同步”。
  
  12. 線程堵塞Blocked有幾個原因造成:
  
  (1)線程在等候一些IO操作 
  
  (2)線程試圖調用另外一個對象的“同步”方法,但那個對象處於鎖定狀態,暫時無法使用。
  
  13.原子型操作(atomic), 對原始型變量(primitive)的操作是原子型的atomic. 意味著這些操作是線程安全的, 但是大部分情況下,我們並不能正確使用,來看看 i = i + 1 , i是int型,屬於原始型變量:
  
  (1)從主內存中讀取i值到本地內存. 
  
  (2)將值從本地內存裝載到線程工作拷貝中. 
  
  (3)裝載變量1. 
  
  (4)將i 加 1. 
  
  (5)將結果給變量i. 
  
  (6)將i保存到線程本地工作拷貝中. 
  
  (7)寫回主內存. 
  
  注重原子型操作只限於第1步到第2步的讀取以及第6到第7步的寫, i的值還是可能被同時執行i=i+1的多線程中斷打攪(在第4步)。
  
  double 和long 變量是非原子型的(non-atomic)。數組是object 非原子型。
  
  14. 由於13條的原因,我們解決辦法是:
  
  class xxx extends Thread{
  
  //i會被經常修改
  
  private int i;
  
  public synchronized int read(){ return i;}
  
  public synchronized void update(){ i = i + 1;}
  
  ..........
  
  }
  
  15. Volatile變量, volatile變量表示保證它必須是與主內存保持一致,它實際是"變量的同步", 也就是說對於volatile變量的操作是原子型的,如用在long 或 double變量前。
  
  16. 使用yield()會自動放棄CPU,有時比sleep更能提升性能。
  
  17. sleep()和wait()的區別是:wait()方法被調用時會解除鎖定,但是我們能使用它的地方只是在一個同步的方法或代碼塊內。
  
  18. 通過制造縮小同步范圍,盡可能的實現代碼塊同步,wait(毫秒數)可在指定的毫秒數可退出wait;對於wait()需要被notisfy()或notifyAll()踢醒。
  
  19. 構造兩個線程之間實時通信的方法分幾步:
  
  (1). 創建一個PipedWriter和一個PipedReader和它們之間的管道;
  
  PipedReader in = new PipedReader(new PipedWriter())
  
  (2). 在需要發送信息的線程開始之前,將外部的PipedWriter導向給其內部的Writer實例out
  
  (3). 在需要接受信息的線程開始之前,將外部的PipedReader導向給其內部的Reader實例in
  
  (4). 這樣放入out的所有東西度可從in中提取出來。
  
  20. synchronized帶來的問題除性能有所下降外,最大的缺點是會帶來死鎖DeadLock,只有通過謹慎設計來防止死鎖,其他毫無辦法,這也是線程難以馴服的一個原因。不要再使用stop() suspend() resume()和destory()方法
  
  21. 在大量線程被堵塞時,最高優先級的線程先運行。
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved