Java基礎之多執行緒
以下是我們Java基礎多執行緒的一些知識點總結:
執行緒中run()和start()的區別:
對於Thread物件來說,當你呼叫的是start(),執行緒會被放到等待佇列,等待CPU排程,不一定馬上執行;無需等待run()方法執行完畢,可以直接執行下面的程式碼;
而呼叫的是run()的話,就是當做普通的方法呼叫,程式還是要順序執行的;
新建執行緒的幾種方式:
實現Runnable介面;裡面實現run()方法;
然後把這個實現了Runnable介面的類就新建為一個Thread t = new Thread(new (實現Runnable介面的類)),呼叫start()方法即可開始一個執行緒了。記住,start()只是開啟,然後就會返回,繼續執行start()下面的語句了。。
執行緒執行器:
我們可以通過不同的執行緒執行器來實現多執行緒的執行,有以下幾種執行器:
ExecutorService exec = Executors.newCachedThreadPool();
ExecutorService exec = Executors.newFixedThreadPool(5);
ExecutorService exec = Executors.newSingleThreadExecutor();
我們可以對比一下這三者的區別:第一個執行會為每一個任務都建立一個執行緒,
而第二個則是可以一次性指定要分配多少執行緒,而第三個則是屬於單執行緒,會一個執行緒一個執行緒的依次執行;
休眠:
會使得任務中斷一段時間,相當於變相的阻塞了,可以給其他執行緒製造機會去執行;
但是我們不能通過sleep()來試圖控制執行緒的順序執行,而是要考慮用同步控制來實現;
讓步:
通過使用yield()方法來給執行緒排程機制一個暗示:你的工作已經完成的差不多了,可以讓別的執行緒使用CPU了,其功能上跟sleep()其實是差不多的。
後臺執行緒:
指在程式執行的時候在後臺提供一種通用服務的執行緒,並且這種執行緒並不屬於程式總共不可或缺的部分,當所有非後臺執行緒結束時,程式終止;由後臺執行緒建立的執行緒也是後臺執行緒;
線上程呼叫start()之前,呼叫setDaemon(true);
實現多執行緒的另一種方式:
通過繼承Thread的方式來實現:而且run()方法是放在建構函式裡面的,也就是說,當初始化一個執行緒的時候,就自動的開啟了執行緒,記得run()方法裡面一般都是一個while()迴圈;
加入一個執行緒:
一個執行緒可以在其他執行緒之上呼叫join()方法,如果某個執行緒在另一個執行緒t上呼叫t.join();此執行緒將被掛起,知道目標執行緒t結束才恢復;
join()方法,你在一個執行緒中join()了一個執行緒進來,你就要等待這個執行緒結束了,才可以把自己這個執行緒給結束掉;join()的底層實現是wait()方法;
同步:
Synchronzied;可以用在方法上,也可以用到類上面;
顯式地使用lock物件,
先用Lock lock = new ReentrantLock();建出一個鎖物件出來,然後在方法裡面,先呼叫lock.lock();然後try語句裡面是方法體,最後記得要在finally裡面加上lock.unlock();這樣就就相當於解鎖了。
區別:
可以看到synchronized和 lock相比起來,lock似乎要加上一些try/catch語句才可以,但是,這也是好處之一,比起synchronized,可以多出來處理的過程,讓使用者出現錯誤的可能性降低;
使用原子類也可以實現資源共享的問題,但是原子類一般很少在常規程式設計中用到,用於效能調優,然後AtomicInteger,AtomicLong等原子類,使用這些的時候,不需要用到synchronized和lock,但是原子類很少用到,所以我們還是用synchronized和lock。