更新時(shí)間:2020-11-16 17:29:01 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1601次
多線程系列一直是Java面試題中的經(jīng)典,多線程(multithreading),是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù),是我們學(xué)習(xí)Java技術(shù)的必學(xué)課程之一。本文我們就根據(jù)以往的資料和前輩們的面試經(jīng)驗(yàn)來(lái)總結(jié)一下必看多線程面試題。
1. 線程和進(jìn)程的區(qū)別?
·性質(zhì)不同
進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。
線程(英語(yǔ):thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。
·適用范圍不同
使用進(jìn)程目的在于清晰地刻畫(huà)動(dòng)態(tài)系統(tǒng)的內(nèi)在規(guī)律,有效管理和調(diào)度進(jìn)入計(jì)算機(jī)系統(tǒng)主存儲(chǔ)器運(yùn)行的程序。
線程為操作系統(tǒng)內(nèi)核調(diào)度的內(nèi)核線程,如Win32線程;由用戶進(jìn)程自行調(diào)度的用戶線程,如Linux平臺(tái)的POSIX Thread;或者由內(nèi)核與用戶進(jìn)程,如Windows 7的線程,進(jìn)行混合調(diào)度。
2.設(shè)計(jì)四個(gè)線程,其中兩個(gè)線程每次對(duì)變量i加1,另外兩個(gè)線程每次對(duì)i減1.
package com.wang.reflect;
/**
* 設(shè)計(jì)四個(gè)線程,其中兩個(gè)線程每次對(duì)變量i加1,另外兩個(gè)線程每次對(duì)i減1.
* @author Administrator
*
*/
public class Demo02 {
private int i=0;
public static void main(String[] args) {
Demo02 demo=new Demo02();
Add add = demo.new Add();
Sub sub = demo.new Sub();
for(int i=1;i<=2;i++){
new Thread(add,"線程"+i).start();
new Thread(sub,"線程"+i).start();
}
}
//定義一個(gè)內(nèi)部類Add,實(shí)現(xiàn)功能每次對(duì)i加一
class Add implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
addOne();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//定義一個(gè)內(nèi)部類Sub,實(shí)現(xiàn)功能每次對(duì)i減1
class Sub implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
subOne();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public synchronized void addOne() {
i++;
System.out.println(Thread.currentThread().getName()+"加一的值為:"+i);
}
public synchronized void subOne(){
i--;
System.out.println(Thread.currentThread().getName()+"減一的值為:"+i);
}
}
3.volatile關(guān)鍵字的作用
一個(gè)非常重要的問(wèn)題,是每個(gè)學(xué)習(xí)、應(yīng)用多線程的Java程序員都必須掌握的。理解volatile關(guān)鍵字的作用的前提是要理解Java內(nèi)存模型,這里就不講Java內(nèi)存模型了,可以參見(jiàn)第31點(diǎn),volatile關(guān)鍵字的作用主要有兩個(gè):
(1)多線程主要圍繞可見(jiàn)性和原子性兩個(gè)特性而展開(kāi),使用volatile關(guān)鍵字修飾的變量,保證了其在多線程之間的可見(jiàn)性,即每次讀取到volatile變量,一定是最新的數(shù)據(jù)
(2)代碼底層執(zhí)行不像我們看到的高級(jí)語(yǔ)言—-Java程序這么簡(jiǎn)單,它的執(zhí)行是Java代碼–>字節(jié)碼–>根據(jù)字節(jié)碼執(zhí)行對(duì)應(yīng)的C/C++代碼–>C/C++代碼被編譯成匯編語(yǔ)言–>和硬件電路交互,現(xiàn)實(shí)中,為了獲取更好的性能JVM可能會(huì)對(duì)指令進(jìn)行重排序,多線程下可能會(huì)出現(xiàn)一些意想不到的問(wèn)題。使用volatile則會(huì)對(duì)禁止語(yǔ)義重排序,當(dāng)然這也一定程度上降低了代碼執(zhí)行效率
從實(shí)踐角度而言,volatile的一個(gè)重要作用就是和CAS結(jié)合,保證了原子性,詳細(xì)的可以參見(jiàn)java.util.concurrent.atomic包下的類,比如AtomicInteger。
4. 創(chuàng)建線程有哪幾種方式?
創(chuàng)建線程有三種方式:
·繼承 Thread 重寫(xiě) run 方法;
·實(shí)現(xiàn) Runnable 接口;
·實(shí)現(xiàn) Callable 接口。
5. 線程有哪些狀態(tài)?
線程的狀態(tài):
·NEW 尚未啟動(dòng)
·RUNNABLE 正在執(zhí)行中
·BLOCKED 阻塞的(被同步鎖或者IO鎖阻塞)
·WAITING 永久等待狀態(tài)
·TIMED_WAITING 等待指定的時(shí)間重新被喚醒的狀態(tài)
·TERMINATED 執(zhí)行完成
6. sleep() 和 wait() 有什么區(qū)別?
·類的不同:sleep() 來(lái)自 Thread,wait() 來(lái)自 Object。
·釋放鎖:sleep() 不釋放鎖;wait() 釋放鎖。
·用法不同:sleep() 時(shí)間到會(huì)自動(dòng)恢復(fù);wait() 可以使用 notify()/notifyAll()直接喚醒。
7. 在 Java 程序中怎么保證多線程的運(yùn)行安全?
方法一:使用安全類,比如 Java. util. concurrent 下的類。
方法二:使用自動(dòng)鎖 synchronized。
方法三:使用手動(dòng)鎖 Lock。
手動(dòng)鎖 Java 示例代碼如下:
Lock lock = new ReentrantLock();
lock. lock();
try {
System. out. println("獲得鎖");
} catch (Exception e) {
// TODO: handle exception
} finally {
System. out. println("釋放鎖");
lock. unlock();
}
8. synchronized 和 volatile 的區(qū)別是什么?
·volatile 是變量修飾符;synchronized 是修飾類、方法、代碼段。
·volatile 僅能實(shí)現(xiàn)變量的修改可見(jiàn)性,不能保證原子性;而 synchronized 則可以保證變量的修改可見(jiàn)性和原子性。
·volatile 不會(huì)造成線程的阻塞;synchronized 可能會(huì)造成線程的阻塞。
9. 為什么要使用多線程
·使用線程可以把占據(jù)時(shí)間長(zhǎng)的程序中的任務(wù)放到后臺(tái)去處理。
·用戶界面更加吸引人,這樣比如用戶點(diǎn)擊了一個(gè)按鈕去觸發(fā)某件事件的處理,可以彈出一個(gè)
·進(jìn)度條來(lái)顯示處理的進(jìn)度。
·程序的運(yùn)行效率可能會(huì)提高。
·在一些等待的任務(wù)實(shí)現(xiàn)上如用戶輸入,文件讀取和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等,線程就比較有用了。
10、如何在兩個(gè)線程之間共享數(shù)據(jù)
通過(guò)在線程之間共享對(duì)象就可以了,然后通過(guò)wait/notify/notifyAll、await/signal/signalAll進(jìn)行喚起和等待,比方說(shuō)阻塞隊(duì)列BlockingQueue就是為線程之間共享數(shù)據(jù)而設(shè)計(jì)的。
多線程作為目前的主流Java技術(shù)之一,一直以來(lái)備受關(guān)注,也是我們參加各大公司的必考知識(shí)點(diǎn)之一。有了上面的10道必看的多線程面試題,小伙伴們可以以此為基礎(chǔ)拓展自己的多線程知識(shí),全面溫習(xí)多線程的各個(gè)知識(shí)點(diǎn),全面學(xué)習(xí)更多的java面試題,在面試中爭(zhēng)取突破自我,取得最好的成績(jī)!
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)