java 中進程和線程區(qū)別

目錄

1.并行和并發(fā)有什么區(qū)別私恬?

  • 并行:多個處理器或多核處理器同時處理多個任務。
  • 并發(fā):多個任務在同一個 CPU 核上炼吴,按細分的時間片輪流(交替)執(zhí)行本鸣,從邏輯上來看那些任務是同時執(zhí)行。

2.線程和進程的區(qū)別硅蹦?

進程:進程指正在運行的程序荣德。

線程:線程是進程中的一個執(zhí)行單元,負責當前進程中程序的執(zhí)行童芹,一個進程中至少有一個線程涮瞻。同一個進程中的多個線程之間可以并發(fā)的執(zhí)行。

3.創(chuàng)建線程有哪幾種方式假褪?

創(chuàng)建線程有三種方式:

  • 繼承 Thread 重寫 run 方法署咽;
  • 實現(xiàn) Runnable 接口;
  • 實現(xiàn) Callable 接口生音。

4.為什么需要定一個類去實現(xiàn)Runnable接口呢宁否?繼承Thread類和實現(xiàn)Runnable接口有啥區(qū)別呢?

實現(xiàn)Runnable接口缀遍,避免了繼承Thread類的單繼承局限性慕匠。覆蓋Runnable接口中的run方法,將線程任務代碼定義到run方法中域醇。

創(chuàng)建Thread類的對象台谊,只有創(chuàng)建Thread類的對象才可以創(chuàng)建線程蓉媳。線程任務已被封裝到Runnable接口的run方法中,而這個run方法所屬于Runnable接口的子類對象青伤,所以將這個子類對象作為參數(shù)傳遞給Thread的構(gòu)造函數(shù)督怜,這樣,線程對象創(chuàng)建時就可以明確要運行的線程的任務狠角。

第二種方式實現(xiàn)Runnable接口避免了單繼承的局限性号杠,所以較為常用。實現(xiàn)Runnable接口的方式丰歌,更加的符合面向?qū)ο笠腆€程分為兩部分,一部分線程對象立帖,一部分線程任務眼溶。繼承Thread類,線程對象和線程任務耦合在一起晓勇。一旦創(chuàng)建Thread類的子類對象堂飞,既是線程對象,有又有線程任務绑咱。實現(xiàn)runnable接口绰筛,將線程任務單獨分離出來封裝成對象,類型就是Runnable接口類型描融。Runnable接口對線程對象和線程任務進行解耦铝噩。

采用繼承Thread類創(chuàng)建線程的優(yōu)點是編寫簡單,如果需要訪問當前線程窿克,無需使用Thread.currentThread()方法骏庸,直接使用this即可獲得當前線程。缺點在于由于該線程類已經(jīng)繼承了Thead類年叮,所以不能再繼承其他的類具被。

而采用實現(xiàn)runnable接口,其優(yōu)點是線程類只是實現(xiàn)了runnable接口谋右,還可以繼承其他的類硬猫。同時,可以多個線程共享同一個目標對象或者資源改执,所以非常適合多個線程處理同一個資源的情況啸蜜。但是這樣的方法也有點缺點,如果需要訪問當前線程辈挂,必須使用Thread.currentThread()方法衬横。

5.runnable和callable的區(qū)別

5.1相同點

都是接口

都可以編寫多線程程序

都采用Thread.start()啟動線程

5.2不同點

Runnable沒有返回值;Callable可以返回執(zhí)行結(jié)果终蒂,是個泛型蜂林,和Future遥诉、FutureTask配合可以用來獲取異步執(zhí)行的結(jié)果

Callable接口的call()方法允許拋出異常;Runnable的run()方法異常只能在內(nèi)部消化噪叙,不能往上繼續(xù)拋

:Callalbe接口支持返回執(zhí)行結(jié)果矮锈,需要調(diào)用FutureTask.get()得到,此方法會阻塞主進程的繼續(xù)往下執(zhí)行睁蕾,如果不調(diào)用不會阻塞苞笨。

6.守護線程是什么?

守護線程是運行在后臺的一種特殊進程子眶。它獨立于控制終端并且周期性地執(zhí)行某種任務或等待處理某些發(fā)生的事件瀑凝。在 Java 中垃圾回收線程就是特殊的守護線程。

7.線程有哪些狀態(tài)臭杰?

線程的狀態(tài):

  • NEW 尚未啟動
  • RUNNABLE 正在執(zhí)行中
  • BLOCKED 阻塞的(被同步鎖或者IO鎖阻塞)
  • WAITING 永久等待狀態(tài)
  • TIMED_WAITING 等待指定的時間重新被喚醒的狀態(tài)
  • TERMINATED 執(zhí)行完成

8.sleep() 和 wait() 有什么區(qū)別粤咪?

  • 類的不同:sleep() 來自 Thread,wait() 來自 Object渴杆。
  • 釋放鎖:sleep() 不釋放鎖寥枝;wait() 釋放鎖。
  • 用法不同:sleep() 時間到會自動恢復磁奖;wait() 可以使用 notify()/notifyAll()直接喚醒脉顿。

9.notify()和 notifyAll()有什么區(qū)別?

notifyAll()會喚醒所有的線程点寥,notify()之后喚醒一個線程。notifyAll() 調(diào)用后来吩,會將全部線程由等待池移到鎖池敢辩,然后參與鎖的競爭,競爭成功則繼續(xù)執(zhí)行弟疆,如果不成功則留在鎖池等待鎖被釋放后再次參與競爭戚长。而 notify()只會喚醒一個線程,具體喚醒哪一個線程由虛擬機控制怠苔。

10.創(chuàng)建線程池有哪幾種方式同廉?

線程池創(chuàng)建有七種方式,最核心的是最后一種:

  • newSingleThreadExecutor():它的特點在于工作線程數(shù)目被限制為 1柑司,操作一個無界的工作隊列迫肖,所以它保證了所有任務的都是被順序執(zhí)行,最多會有一個任務處于活動狀態(tài)攒驰,并且不允許使用者改動線程池實例蟆湖,因此可以避免其改變線程數(shù)目;
  • newCachedThreadPool():它是一種用來處理大量短時間工作任務的線程池玻粪,具有幾個鮮明特點:它會試圖緩存線程并重用隅津,當無緩存線程可用時诬垂,就會創(chuàng)建新的工作線程;如果線程閑置的時間超過 60 秒伦仍,則被終止并移出緩存结窘;長時間閑置時,這種線程池充蓝,不會消耗什么資源隧枫。其內(nèi)部使用 SynchronousQueue 作為工作隊列;
  • newFixedThreadPool(int nThreads):重用指定數(shù)目(nThreads)的線程棺克,其背后使用的是無界的工作隊列悠垛,任何時候最多有 nThreads 個工作線程是活動的。這意味著娜谊,如果任務數(shù)量超過了活動隊列數(shù)目确买,將在工作隊列中等待空閑線程出現(xiàn);如果有工作線程退出纱皆,將會有新的工作線程被創(chuàng)建湾趾,以補足指定的數(shù)目 nThreads;
  • newSingleThreadScheduledExecutor():創(chuàng)建單線程池派草,返回 ScheduledExecutorService搀缠,可以進行定時或周期性的工作調(diào)度;
  • newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()類似近迁,創(chuàng)建的是個 ScheduledExecutorService艺普,可以進行定時或周期性的工作調(diào)度,區(qū)別在于單一工作線程還是多個工作線程鉴竭;
  • newWorkStealingPool(int parallelism):這是一個經(jīng)常被人忽略的線程池歧譬,Java 8 才加入這個創(chuàng)建方法,其內(nèi)部會構(gòu)建ForkJoinPool搏存,利用Work-Stealing算法瑰步,并行地處理任務,不保證處理順序璧眠;
  • ThreadPoolExecutor():是最原始的線程池創(chuàng)建缩焦,上面1-3創(chuàng)建方式都是對ThreadPoolExecutor的封裝。

11.線程池都有哪些狀態(tài)责静?

  • RUNNING:這是最正常的狀態(tài)袁滥,接受新的任務,處理等待隊列中的任務泰演。
  • SHUTDOWN:不接受新的任務提交呻拌,但是會繼續(xù)處理等待隊列中的任務。
  • STOP:不接受新的任務提交睦焕,不再處理等待隊列中的任務藐握,中斷正在執(zhí)行任務的線程靴拱。
  • TIDYING:所有的任務都銷毀了,workCount 為 0猾普,線程池的狀態(tài)在轉(zhuǎn)換為 TIDYING 狀態(tài)時袜炕,會執(zhí)行鉤子方法 terminated()。
  • TERMINATED:terminated()方法結(jié)束后初家,線程池的狀態(tài)就會變成這個偎窘。

12.線程池中 submit() 和 execute() 方法有什么區(qū)別?

  • execute():只能執(zhí)行 Runnable 類型的任務溜在。
  • submit():可以執(zhí)行 Runnable 和 Callable 類型的任務陌知。

13.在 Java 程序中怎么保證多線程的運行安全?

  • 方法一:使用安全類掖肋,比如 Java. util. concurrent 下的類仆葡。
  • 方法二:使用自動鎖 synchronized。
  • 方法三:使用手動鎖 Lock志笼。
Lock lock = new ReentrantLock();
lock. lock();
try {
    System. out. println("獲得鎖");
} catch (Exception e) {
    // TODO: handle exception
} finally {
    System. out. println("釋放鎖");
    lock. unlock();
}

14.線程同步的方式

線程同步的方式有兩種:

  • 方式1:同步代碼塊
  • 方式2:同步方法

同步代碼塊: 在代碼塊聲明上 加上synchronized

synchronized (鎖對象) {
  可能會產(chǎn)生線程安全問題的代碼
}

同步代碼塊中的鎖對象可以是任意的對象沿盅;但多個線程時,要使用同一個鎖對象才能夠保證線程安全纫溃。

同步方法:在方法聲明上加上synchronized

public synchronized void method(){
   可能會產(chǎn)生線程安全問題的代碼
}

同步方法中的鎖對象是 this

15.Lock

查閱Lock接口描述腰涧,Lock 實現(xiàn)提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。

Lock提供了一個更加面對對象的鎖紊浩,在該鎖中提供了更多的操作鎖的功能窖铡。

我們使用Lock接口,以及其中的lock()方法和unlock()方法替代同步坊谁,對電影院賣票案例中Ticket類進行如下代碼修改:

package cn.jxufe.java.chapter10.demo06;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test01ThreadSafty {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Ticket mt = new Ticket();
        Thread th1 = new Thread(mt);
        Thread th2 = new Thread(mt);
        Thread th3 = new Thread(mt);
        th1.start();
        th2.start();
        th3.start();

    }

}

/*
 *  使用JDK1.5 的接口Lock,替換同步代碼塊,實現(xiàn)線程的安全性
 *  Lock接口方法:
 *     lock() 獲取鎖
 *     unlock()釋放鎖
 *  實現(xiàn)類ReentrantLock
 */
class Ticket implements Runnable {
    private static int ticket = 10;
    //在類的成員位置,創(chuàng)建Lock接口的實現(xiàn)類對象
    private Lock l = new ReentrantLock();
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
            //調(diào)用Lock接口方法lock獲取鎖
            l.lock();
            if (ticket > 0) {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "賣票:還剩下" + ticket-- + "張票");
            }
            //釋放鎖,調(diào)用Lock接口方法unlock
            l.unlock();
        }
    }

}

16.死鎖

是指兩個或兩個以上的進程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去

(1) 因為系統(tǒng)資源不足万伤。
(2) 進程運行推進順序不合適。
(3) 資源分配不當?shù)取?/p>

當線程 A 持有獨占鎖a呜袁,并嘗試去獲取獨占鎖 b 的同時,線程 B 持有獨占鎖 b简珠,并嘗試獲取獨占鎖 a 的情況下阶界,就會發(fā)生 AB 兩個線程由于互相持有對方需要的鎖,而發(fā)生的阻塞現(xiàn)象聋庵,我們稱為死鎖膘融。

死鎖的四個必要條件:

(1)** 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時祭玉,對已獲得的資源保持不放氧映。
(3)
不剝奪條件:**進程已獲得的資源,在末使用完之前脱货,不能強行剝奪岛都。
(4) 循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系律姨。

17.解決死鎖的方法

  • 盡量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock)臼疫,設置超時時間择份,超時可以退出防止死鎖。
  • 盡量使用 Java. util. concurrent 并發(fā)類代替自己手寫鎖烫堤。
  • 盡量降低鎖的使用粒度荣赶,盡量不要幾個功能用同一把鎖。
  • 盡量減少同步的代碼塊鸽斟。

18.synchronized 和 Lock 有什么區(qū)別拔创?

  • synchronized 可以給類、方法富蓄、代碼塊加鎖剩燥;而 lock 只能給代碼塊加鎖。
  • synchronized 不需要手動獲取鎖和釋放鎖格粪,使用簡單躏吊,發(fā)生異常會自動釋放鎖,不會造成死鎖帐萎;而 lock 需要自己加鎖和釋放鎖比伏,如果使用不當沒有 unLock()去釋放鎖就會造成死鎖。
  • 通過 Lock 可以知道有沒有成功獲取鎖疆导,而 synchronized 卻無法辦到赁项。

19.synchronized 和 ReentrantLock 區(qū)別是什么?

synchronized 早期的實現(xiàn)比較低效澈段,對比 ReentrantLock悠菜,大多數(shù)場景性能都相差較大,但是在 Java 6 中對 synchronized 進行了非常多的改進败富。

主要區(qū)別如下:

  • ReentrantLock 使用起來比較靈活悔醋,但是必須有釋放鎖的配合動作;
  • ReentrantLock 必須手動獲取與釋放鎖兽叮,而 synchronized 不需要手動釋放和開啟鎖芬骄;
  • ReentrantLock 只適用于代碼塊鎖,而 synchronized 可用于修飾方法鹦聪、代碼塊等账阻。
  • volatile 標記的變量不會被編譯器優(yōu)化;synchronized 標記的變量可以被編譯器優(yōu)化泽本。

Note:
本文內(nèi)容都是來源網(wǎng)上淘太,參考原文為java面試

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蒲牧,更是在濱河造成了極大的恐慌撇贺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件造成,死亡現(xiàn)場離奇詭異显熏,居然都是意外死亡,警方通過查閱死者的電腦和手機晒屎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門喘蟆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鼓鲁,你說我怎么就攤上這事蕴轨。” “怎么了骇吭?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵橙弱,是天一觀的道長。 經(jīng)常有香客問我燥狰,道長棘脐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任龙致,我火速辦了婚禮蛀缝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘目代。我一直安慰自己屈梁,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布榛了。 她就那樣靜靜地躺著在讶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪霜大。 梳的紋絲不亂的頭發(fā)上构哺,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音战坤,去河邊找鬼遮婶。 笑死,一個胖子當著我的面吹牛湖笨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蹦骑,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼慈省,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起边败,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤袱衷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后笑窜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體致燥,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年排截,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫌蚤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡断傲,死狀恐怖脱吱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情认罩,我是刑警寧澤箱蝠,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站垦垂,受9級特大地震影響宦搬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜劫拗,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一间校、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杨幼,春花似錦撇簿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至欲逃,卻和暖如春找蜜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稳析。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工洗做, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人彰居。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓诚纸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親陈惰。 傳聞我的和親對象是個殘疾皇子畦徘,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354