多線程的線程池


1.什么是Java內存模型?
    Java程序是要運行在Java虛擬機上面的,Java內存模型(Java Memory Model,JMM)就是一種符合內存模型規范的,屏蔽了各種硬件和操作系統的訪問差異的,保證了Java程序在各種平台下對內存的訪問都能保證效果一致的機制和規范。
2.MySQL的事務隔離級別?
    MySQL的事務隔離級別其實跟spring的事務隔離級別一樣,都是1、Read Uncommitted(讀取未提交內容,也被稱之為臟讀),2、Read Committed(讀取提交內容),3、Repeatable Read(可重讀,MySQL的默認事務隔離級別),4、Serializable(可串行化)
3.Spring的原理?
    spring的核心是IOC和AOP,IOC是依賴注入和控制反轉,注入方式可以分為set注入,構造器注入,接口注入。IOC就是一個容器,負責實例化、定位、配置應用程序中的對象及遍歷這些對象間的依賴。IOC的思想是:Spring來管理這些,對象只用處理本身業務關系。控制反轉:獲得依賴的方式反轉了,原本有程序員自己創建的對象交給了Spring來管理。
4.重寫equals為何要重寫hashCode?(==比較的是地址,equals比較的對象內容)
    判斷兩個對象是否相等,比較的是hashcode,如果你重載了equals,而hashcode沒做出改變,那么可能造成兩個對象明明是相等的,而hashcode卻不一樣,造成無法認定兩個對象是否相等。
5.Object中的幾個方法
    1.hashCode():獲取用戶的hash值,用於檢索
    2.clone():創建並返回此對象的副本
    3.equals(Object obj) :指示一些其他對象是否等於此。
    4.getClass() :返回此 Object的運行時類。
    5.toString() :返回對象的字符串表示形式。
    6.wait():導致當前線程等待,直到另一個線程調用該對象的 notify()方法或 notifyAll()方法。
    7.notify()和notifyAll():喚醒正在等待對象監視器的單個/所有線程
6.動態代理的兩種方式,以及區別
    代理方式分為JDK動態代理和cglib動態代理
        JDK動態代理只能對實現了接口的類生成代理,而不能針對類
        cglib動態代理是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法。
7.淺談線程池,在線程池創建一個線程的過程
    線程池:創建線程需要花費時間,如果等任務來了再去創建,效率難免有點低,從JDK1.5開始,Java API提供了Executor框架可以創建不同的線程池。
    corePoolSize:核心線程數,能夠同時執行的任務數量
    maximumPoolSize:最大線程數,表明線程中最多能夠創建的線程數量
    keepAliveTime:空閑的線程保留時間
    TimeUnit:空閑線程的保留時間單位
    workQueue:阻塞等待線程的隊列
    threadFactory:創建線程的工廠
    handler:當任務數超過了maximumPoolSize時,對任務的處理策略,默認策略時拒絕添加
    執行過程:當線程數小於corePoolSize時,每添加一個任務,就會立即開啟線程執行;當corePoolSize滿了的時候,后面添加的任務將放入緩沖隊列workQueue等待;當workQueue滿的時候,看是否超過了maximumPoolSize線程數,如果超過,則拒絕執行,如果沒有,則創建線程立即執行。
8.悲觀鎖和樂觀鎖和樂觀鎖實現之CAS操作
    悲觀鎖:總是假設最壞的情況,每次拿數據的時候都會認為別人會修改數據,所以每次拿數據時都會上鎖,這樣別人拿數據時候就會進入阻塞狀態,Java中的synchronized就是悲觀鎖。關系型數據庫中的行鎖,讀鎖,寫鎖都是悲觀鎖。
    樂觀鎖:每次拿數據時都認為別人不會修改,不會上鎖,但在更新的時候會判斷一下在此期間別人有沒有更新這個數據,樂觀鎖用於多讀的類型,可以提高吞吐量。
    CAS(Compare-And-Swap,比較和替換),其具有三個操作數:內存地址V,舊的預期值A,新的預期值B。更新變量的時候,只有當變量的預期值A和內存地址V當中的實際值相同時,才會將內存地址V對應的值修改為B。CAS值的替換是原子性的。CAS是樂觀鎖技術,當多個線程使用CAS去更新一個變量的時候,如果存在競爭,則沒有獲取資源的進程不會立即掛起,而是采用讓線程進入到一種忙循環中,等過一段時間看能否獲取鎖,如果超出時間則掛起。缺點就是存在ABA問題(我內存對象從A變成B在變成A,CAS會當成沒有變化,實際有變化),循環時間長開銷大(一直和預期不對的情況下,會一直循環)
9.線程的狀態都有哪些?
    新建狀態(new,線程還沒有開始執行),就緒狀態(Runnable,一個新建的線程並不會自動運行,需要調用線程的start()方法),運行狀態(Running,開始執行run()方法),阻塞狀態(blocked,運行過程中,可能由於各種原因進入阻塞狀態),死亡狀態(dead,run方法自然退出,線程執行完畢,或者捕獲了一個異常終止了run方法)
    阻塞狀態的原因:    1.線程通過調用sleep方法進入睡眠狀態
            2.線程試圖得到一個鎖,而這個鎖正被其他線程持有
            3.線程正在等待某個觸發條件
10.sleep和wait的區別:
    sleep()方法屬於thread類的,而wait()方法屬於Object類的;sleep()方法導致了程序暫停執行的特定時間,讓出CPU給其他線程,但是他的監控狀態一直保持,當到達指定的時間又自動回到運行狀態,調用sleep()方法的過程中,線程不會釋放對象鎖;而當調用了wait()方法的時候,線程會放棄對象鎖,進入到此對象的等待鎖池,只有針對了此對象調用notify()或者notifyAll()方法后本線程才進入到對象鎖池准備。如果線程重新獲得對象的鎖就可以進入就緒狀態
11.Java線程中的堆和棧
    每個線程都會有自己的棧內存,用於存儲本地變量、方法參數和棧調用,一個線程中存儲的變量對其他線程時不可見的。而堆是所有線程共享的一片公共內存區域,對象都在堆內創建,為了提高效率,線程會從堆內存中緩存到自己的棧,如果多個線程使用該變量就可能引發問題,這時volatile變量就可以發揮作用,它要求線程從主存中讀取變量的值。
12.三個線程如何保證順序執行
    用Thread.join()方法
13.怎么檢測一個線程是否擁有鎖?
    java.long.Thread中有一個方法就holdslocak()方法,返回值為Boolean類型
    Thread類中的yield方法可以暫停當前正在執行的線程對象,讓其他有相同優先級的線程執行,讓當前線程由“運行狀態”進入到“就緒狀態”,
14.如何避免死鎖
    多線程的死鎖:是指兩個或者兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的情況。死鎖必定滿足以下條件:
    1.互斥條件:一個資源每次只能被一個進程使用
    2.請求和保持條件:一個進程因請求資源而被阻塞時,對已獲得的資源保持不放
    3.不剝奪條件:進程已獲得資源,在未使用完之前,不能強行剝奪
    4.循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系
    最簡單的解決方式:阻塞循環等待條件,以一定的順序來操作
15.什么時阻塞式方式
    阻塞式方式是指程序會一直等待該方法完成期間不可做其他事情。
16. java中ConcurrentHashMap的並發度是什么?
    ConcurrentHashMap會把實際map划分若干部分來實現它的可擴展性和線程安全,這種划分是使用並發度獲得的,它是ConcurrentHashMap類構造函數的一個可選參數,默認值為16,這樣可以在多線程情況下就能避免爭用鎖。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM