JAVA多線程入門
為什麽使用多線程
進程之間不能共享內存,但線程之間共享內存很容易
系統創建進程需要為該進程重新分配系統資源,但創建線程代價小得多,因此使用多線程來實現多任務並發比多進程的效率高
JAVA內置了多線程功能支持,而不是單純的作為底層操作系統的調度方式,從而簡化了JAVA的多線程編程
線程的創建
繼承
Thread
類(可直接使用this
關鍵字獲得當前對象,多個線程無法共享線程類的實例變量)實現
Runnable
接口(必須使用Thread.currentThread()
方法,多個線程可以共享線程類的實例變量)使用
Callable
和Future
創建線程(call()
方法作為線程執行體,可以有返回值去,可以聲明拋出異常)
線程的生命周期
新建(New)--使用
new
關鍵詞新建一個線程就緒(Runnable)--調用
start()
方法運行(Running)--處於就緒狀態的線程獲得CPU,開始執行
run()
方法體阻塞(Blocked)
線程調用sleep()
方法主動放棄所占用的處理器資源
線程調用了一個阻塞式的IO方法
線程試圖獲得一個同步監視器,但該監視器被其他線程所持有
線程在等待某個通知
程序調用了線程的suspend()
方法將該線程掛起(容易導致死鎖)死亡(Dead)
run()
方法或call()
方法執行完成,線程正常結束
線程拋出一個未捕獲的異常
直接調用該線程的stop()
方法來結束該線程(容易導致死鎖)
控制線程
join()
join()
方法時,調用線程被阻塞,直到join()
方法加入的join線程執行完為止setDemon()
方法--將指定線程設置為守護線程sleep()
方法--暫停線程的執行,並進入阻塞狀態yield()
方法--暫停線程的執行,並進入就緒狀態setPriority()
方法--改變線程的優先級,讓優先級高的線程獲得更多的執行機會
線程同步
同步代碼塊(同步監視器為
obj
)synchronized(obj){ ... }
同步方法(同步監視器為
this
)public synchronized void draw{ }
同步鎖(Lock)
//定義鎖對象private final ReentrantLock lock = new ReentrantLock();//加鎖lock.lock();//釋放鎖lock.unlock();
釋放同步監視器的鎖定
當前線程的同步方法,同步代碼塊執行結束
當前線程在同步方法,同步代碼塊遇到
break
,return
終止了繼續執行當前線程在同步方法,同步代碼塊出現未處理的異常
當前線程執行同步方法,同步代碼塊時執行了同步監視器對象的
wait()
方法
不釋放同步監視器的情況
線程執行同步方法,同步代碼塊時,程序調用
Thread.sleep()
,Thread.yield()
方法來暫停當前線程的執行線程執行同步代碼塊時,其他線程調用了該線程的
suspend()
方法將該線程掛起
線程通信
傳統的線程通信
對於使用synchronized
修飾的同步方法或代碼塊,借助Object
類提供的wait()
,notify()
,notifyAll()
方法使用Condition控制線程通信
如果程序顯式使用Lock
對象保證同步,則使用Condition
對象的await()
,signal()
,signalAll()
來控制程序的協調運行使用阻塞隊列(BlockingQueue)控制線程通信
BlockingQueue
接口:put()
方法嘗試把元素放入隊列中,入托隊列元素已滿,則阻塞該線程,take()
方法嘗試從隊列頭部去取出元素,如果隊列元素已空,則阻塞該線程
線程池
Executors
工廠類來產生線程池//返回ExecutorService對象的方法newCachedThreadPool() newFixedThreadPool(int nThreads) newSingleThreadExecutor()//返回ScheduleExecutorService線程池的方法newScheduledThreadPool(int corePoolSize) newSingleThreadScheduledExecutor()//生成work stealing池,相當於後臺線程池ExecutorService newWorkStealingPool(int parallelism)ExecutorService newWorkStealingPool()
創建
Runnable
或者Callable
實現類的實例調用
ExecutorService
對象的submit()
方法來提交Runnable
或者Callable
實例調用
ExecutorService
對象的shutdown()
方法關閉線程池
ForkJoinPool
--充分利用多核CPU
創建
ForkJoinPool
實例創建有繼承了返回值的
RecursiveTask
或無返回值的RecursiveAction
實例調用
ForkJoinPool
的submit(ForkJoinTask task)
或submit(ForkJoinAction action)
方法來執行指定任務線程相關類
ThreadLocal
類
隔離多個線程的數據共享,從根本上避免多個線程之間對共享資源的競爭包裝線程不安全的集合類
使用Collections
提供的類方法包裝線程安全的集合類
以
Concurrent
開頭的集合類以
CopyOnWrite
開頭的集合類
JAVA多線程入門