進程跟線程的區別
- 進程process是操作系統中運行的一個任務,占有一定的內存資源;線程thread是進程中包含的一個或多個執行單元,歸屬於進程
多線程的應用場景
- 一個程序需要同時完成多個任務時
- 多個線程效率更高的情況下,比如下載
並發原理
- 對於單核cpu來說,多線程並不是同時進行的,操作系統將時間分成了多個時間片,大概均勻的分配給線程,到達某個線程的時間段,該線程運行,其余時間待命,這樣從微觀上看,一個線程是走走停停的,宏觀感官上,在某一時刻似乎所有線程都在運行。並發是針對時間片段來說的,在某個時間段內多個線程處於runnable到running之間,但每個時刻只有一個線程在running,這叫做並發。
創建線程
- 繼承Thread類,重寫run方法
- 定義線程體Runnable run1,實現Runnable接口,Thread t = new Thread(run1);
- 繼承Thread創建線程相對於實現Runnable接口來創建,有兩點壞處,一是將線程與任務形成了強耦合關系,破壞了線程的復用性,二是java中的類只能繼承一個父類,繼承Thread阻斷了其它的繼承關系,而一個類可以實現多個接口,很靈活
- thread的start方法,用於將線程納入到線程調度 ,線程進入runnable狀態
- 可以使用匿名內部類的方式創建線程
java中線程的幾個常用api
- Thread.currentThread(); //獲取當前線程,返回Thread
- Thread.getId(); //獲取線程id,返回long
- Thread.getName(); //獲取線程名字,返回String
- Thread.getPriority(); //獲取線程優先級,返回int,提供了三個常量(MIN_PRIORITY、MAX_PRIORITY、NORM_PRIORITY)
- Thread.getState(); //獲取線程狀態
- Thread.isAlive(); //獲取線程是否活動
- Thread.isDaemon(); //返回是否是守護線程
- Thread.isInterrupted(); //返回是否中斷
- static Thread.interrupted();//返回是否中斷,並重置中斷狀態為false
- Thread.sleep(ms); //使線程進入休眠,sleepblock,休眠結束回到Runnable
- static Thread.yield(); //static方法,讓出時間片並回到Runnable
- Thread.join(); //比如在線程b的方法中加入a.join,代表等待線程a執行完畢,再執行b
守護線程
- setDaemon(boolean b); //需要在start方法調用前進行設置
- 當線程只剩下守護線程時,所有守護線程終止
- 比如GC
synchronized
- 多個線程並發讀寫同一個臨界資源,會引發線程並發安全問題
** 臨界資源:多線程共享實例變量;多線程共享靜態資源變量
** 解決辦法:異步變同步 - 同步與異步
** 有先后順序的運行方式是同步
** 沒有先后順序,由線程調度隨機分配時間片段運行,是異步 - synchronized是java中的同步鎖
- synchronized可以修飾某個方法,使訪問這個方法的線程同步
- synchronized(object){代碼塊}; //object必須是同一對象,鎖才有效用
** 如果synchronized在一個非靜態方法中,通常鎖對象是this
** synchronized也可以直接修飾代碼塊
wait¬ify
- 多線程之間協調工作
- 條件不滿足,等待wait,條件滿足notify,等待喚醒
- 如果想在一個線程上等待,在另一個線程上notify,那么需要給這兩個方法加鎖
** synchronized(obj){obj.wait();}
** synchronized(obj){obj.notify();} - 如果多個線程在一個線程上等待,notify()只能喚醒一個,notifyAll()可以喚醒所有
線程安全API與非線程安全API
- StringBuffer 同步的,線程安全,synchronized append()]
- StringBuilder 不同步的,線程不安全的,append()
- Vector Hashtable ConcurrentHashMap同步,線程安全
- ArrayList HashMap 不同步,線程不安全
- Collections.synchronizedList(list) 獲取線程安全的list集合
- Collections.synchronizedSet(set) 獲取線程安全的set集合
- Collections.synchronizedMap(map) 獲取線程安全的map
線程池
- 重用與限制數量
- 線程池的使用與ExecutorService實現:另開一章