1、初始啟動變慢
在某些平台上建立和啟動新線程是相對較慢的操作,在性能至上的應用程式中,這可能是很大的缺點。不過,線程池技術為這類問題提供了簡單的解決方案,執行很多并發操作的應用程式通常會使用線程池,尤其是當應用程式操作的完成速度較快時更适合使用線程池。線程池的概念類似資料庫連接配接池。
2、資源利用
每個線程都需要配置設定自身的棧,棧就是包含變量值和其他執行資訊的存儲區。除了棧之外,線程還要使用 其他系統資源,但不同JVM中所用的資源數量和類型也各不相同。雖然有時需要建立大量的線程,但所用平台可能會限制建立線程的數量。即使所有平台沒有顯式限制所能建立的線程數量,但一般根據處理器速度和系統可用記憶體也會有所限制。
這個問題雖然無法消除,但可以通過線程池技術得到控制。使用線程池除了你能消除建立新線程占用的系統開銷外,還能夠減少線程的建立數量。當然,要假定應用程式允許線程池管理器來控制建立線程的時刻以及建立線程的數量。Java中并未實作線程池管理器。
3、複雜性增加
顯然,在應用程式中使用線程的最大缺點是它會增加複雜性。例如,調試單線程應用程式時很容易觀察應用程式的執行流程,但多線程應用程式中就很難觀察執行流程。
線程安全還往往關系到對象設計,線程在修改對象資料時,另一個對象就無法讀寫該資料。這裡的資料指對象中封裝的資訊,一個資料項可能由對象的一個以上字段構成。
另一個更複雜的問題是多個線程間的資源共享。這裡的資源指能夠被多個線程同時通路的任意實體,大多數情況下您需要負責調配線程對資源的使用。例如,各種Swing元件本身都不是線程安全的,那麼就要考慮如何調配應用程式的線程和AWT事件線程對Swing元件的使用。通常使用SwingUtilities類中的invokeAndWait()方法和invokeLate()方法,把對可視元件的修改委托給AWT事件線程。
資源共享的定義
在該方法中的定義的局部變量無法在方法外被通路,因而多個線程執行同一對象的該方法時無法共享該變量。例如,假設運作如下應用程式,其中建立兩個線程使用同一個Runnable對象執行個體:
1 public class ThreadShare implements Runnable{
2
3 public static void main(String[] args){
4 ThreadShare ts = new ThreadShare();
5 Thread t1 = new Thread(ts);
6 Thread t2 = new Thread(ts);
7 t1.start();
8 t2.start();
9 }
10 public void run(){
11 int nonSharedValue = 100;
12 nonSharedValue += 100;
13 System.out.println("value:" + nonSharedValue);
14 }
15 }
由于nonSharedValue變量時在run()方法中定義的,是以它是方法的局部變量,無法被兩個線程共享。則每個線程都會有各自的nonSharedValue副本,運作該應用程式産生的輸出結果如下:
value: 200
value: 200
但如果修改應用程式使run()方法遞增一個執行個體變量,則該變量為共享資源:
1 public class ThreadShare implements Runnable{
2
3 int nonSharedValue = 100;
4 public static void main(String[] args){
5 ThreadShare ts = new ThreadShare();
6 Thread t1 = new Thread(ts);
7 Thread t2 = new Thread(ts);
8 t1.start();
9 t2.start();
10 }
11 public void run(){
12
13 nonSharedValue += 100;
14 System.out.println("value:" + nonSharedValue);
15 }
16 }
轉載于:https://www.cnblogs.com/freeabyss/archive/2013/06/07/3187050.html