中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

深圳網(wǎng)站建設(shè)信科獨家友情鏈接外鏈

深圳網(wǎng)站建設(shè)信科獨家,友情鏈接外鏈,云服務(wù)器管理,河北做網(wǎng)站找誰在java 多線程 面試中最多問題1.悲觀鎖和樂觀鎖;2.synchronized和lock的區(qū)別;3.可重入鎖和非可重入鎖的區(qū)別;4.多線程是解決什么問題的;5.線程池解決什么問題的;6.線程池原理;7.線程池使用注意事項&#xf…

在java 多線程 面試中最多問題1.悲觀鎖和樂觀鎖;2.synchronized和lock的區(qū)別;3.可重入鎖和非可重入鎖的區(qū)別;4.多線程是解決什么問題的;5.線程池解決什么問題的;6.線程池原理;7.線程池使用注意事項;8.AQS原理;9.ReentranLock源碼,設(shè)計原理,整體過程等問題;

一?面試中關(guān)于 synchronized 關(guān)鍵字的問答

1.說一說對synchronized關(guān)鍵字的了解?

答:synchronized關(guān)鍵字解決的是多個線程之間訪問資源的同步性,synchronized關(guān)鍵字可以保證被它修飾的方法或者代碼塊在任意時刻只能有一個線程執(zhí)行。
另外,在 Java 早期版本中,synchronized屬于重量級鎖,效率低下,因為監(jiān)視器鎖(monitor)是依賴于底層的操作系統(tǒng)的 Mutex Lock 來實現(xiàn)的,Java 的線程是映射到操作系統(tǒng)的原生線程之上的。如果要掛起或者喚醒一個線程, 都需要操作系統(tǒng)幫忙完成,而操作系統(tǒng)實現(xiàn)線程之間的切換時需要從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài),這個狀態(tài)之間的轉(zhuǎn)換需要 ? 相對比較長的時間,時間成本相對較高,這也是為什么早期的 synchronized 效率低的原因。慶幸的是在 Java 6 之后Java 官方對從 JVM 層面對synchronized 較大優(yōu)化,所以現(xiàn)在的 synchronized 鎖效率也優(yōu)化得很不錯了。JDK1.6對鎖的實現(xiàn)引入了大量的優(yōu)化,如自旋鎖、適應(yīng)性自旋鎖、鎖消除、鎖粗化、偏向鎖、輕量級鎖等技術(shù)來減少鎖操作的 ? 開銷。

2.說一說synchronized關(guān)鍵字的使用和實際項目中應(yīng)用

答:synchronized關(guān)鍵字最主要的三種使用方式:
修飾實例方法,作用于當(dāng)前對象實例加鎖,進(jìn)入同步代碼前要獲得當(dāng)前對象實例的鎖
修飾靜態(tài)方法,作用于當(dāng)前類對象加鎖,進(jìn)入同步代碼前要獲得當(dāng)前類對象的鎖 ?。也就是給當(dāng)前類加鎖,會作用于類的所有對象實例,因為靜態(tài)成員不屬于任何一個實例對象,是類成員( ?static ? 表明這是該類的一個靜態(tài)資源,不管new了多少個對象,只有一份,所以對該類的所有對象都加了鎖)。所以如果一個線程A調(diào)用一個實 ? ?例對象的非靜態(tài) synchronized 方法,而線程B需要調(diào)用這個實例對象所屬類的靜態(tài) synchronized 方法,是允許的,不會發(fā)生互斥現(xiàn)象,因為訪問靜態(tài) synchronized 方法占用的鎖是當(dāng)前類的鎖,而訪問非靜態(tài)synchronized 方法占用的鎖是當(dāng)前實例對象鎖。
修飾代碼塊,指定加鎖對象,對給定對象加鎖,進(jìn)入同步代碼庫前要獲得給定對象的鎖。 和 synchronized 方法一樣,synchronized(this)代碼塊也是鎖定當(dāng)前對象的。synchronized 關(guān)鍵字加到 static 靜態(tài)方法和synchronized(class)代碼塊上都是是給 Class ?類上鎖。這里再提一下:synchronized關(guān)鍵字加到非 static ?靜態(tài)方法上是給對象實例上鎖。另外需要注意的是:盡量不要使用 synchronized(String a) 因為JVM中,字符串常量池具有緩沖功能!
下面我已一個常見的面試題為例講解一下 synchronized 關(guān)鍵字的具體使用。

面試中面試官經(jīng)常會說:“單例模式了解嗎?來給我手寫一下!給我解釋一下雙重檢驗鎖方式實現(xiàn)單例模式的原理 ?唄!”

雙重校驗鎖實現(xiàn)對象單例(線程安全)雙重校驗鎖實現(xiàn)對象單例(線程安全)

public class Singleton {private volatile static Singleton uniqueInstance;private Singleton() {
}public static Singleton getUniqueInstance() {
//先判斷對象是否已經(jīng)實例過,沒有實例化過才進(jìn)入加鎖代碼if (uniqueInstance == null) {//類對象加鎖synchronized (Singleton.class) { if (uniqueInstance == null) {uniqueInstance = new Singleton();}}}return uniqueInstance;}
}

另外,需要注意 uniqueInstance 采用 volatile 關(guān)鍵字修飾也是很有必要。

uniqueInstance 采用 volatile 關(guān)鍵字修飾也是很有必要的, uniqueInstance = ?new ?Singleton(); ?這段代碼其實是分為三步執(zhí)行:
1.為 uniqueInstance 分配內(nèi)存空間
2.初始化 uniqueInstance
3.將 uniqueInstance 指向分配的內(nèi)存地址
但是由于 JVM ?具有指令重排的特性,執(zhí)行順序有可能變成 ?1->3->2。指令重排在單線程環(huán)境下不會出先問題,但是在多線程環(huán)境下會導(dǎo)致一個線程獲得還沒有初始化的實例。例如,線程 T1 執(zhí)行了 1 和 3,此時 T2 調(diào)用getUniqueInstance() ?后發(fā)現(xiàn) ?uniqueInstance ?不為空,因此返回 ?uniqueInstance,但此時 ?uniqueInstance ?還未被初始化。
使用 volatile 可以禁止 JVM 的指令重排,保證在多線程環(huán)境下也能正常運行。

3.Volatile關(guān)鍵字的作用是什么?

Volatile關(guān)鍵字的作用主要有如下兩個:
1.線程的可見性:當(dāng)一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。
2. 順序一致性:禁止指令重排序。

可見性測試代碼:

public class VolatileTest {boolean flag = true;public void updateFlag() {this.flag = false;System.out.println("修改flag值為:" + this.flag);}public static void main(String[] args) {VolatileTest test = new VolatileTest();new Thread(() -> {while (test.flag) {}System.out.println(Thread.currentThread().getName() + "結(jié)束");}, "Thread1").start();new Thread(() -> {try {Thread.sleep(2000);test.updateFlag();} catch (InterruptedException e) {}}, "Thread2").start();}
}

打印結(jié)果如下,我們可以看到雖然線程Thread2已經(jīng)把flag 修改為false了,但是線程Thread1沒有讀取到flag修改后的值,線程一直在運行

修改flag值為:false

我們把flag 變量加上volatile:

volatile  boolean flag = true;

重新運行程序,打印結(jié)果如下。Thread1結(jié)束,說明Thread1讀取到了flage修改后的值

修改flag值為:false
Thread1結(jié)束

4.Volatile與Synchronized比較

Volatile是輕量級的synchronized,因為它不會引起上下文的切換和調(diào)度,所以Volatile性能更好。
Volatile只能修飾變量,synchronized可以修飾方法,靜態(tài)方法,代碼塊。
Volatile對任意單個變量的讀/寫具有原子性,但是類似于i++這種復(fù)合操作不具有原子性。而鎖的互斥執(zhí)行的特性可以確保對整個臨界區(qū)代碼執(zhí)行具有原子性。
多線程訪問volatile不會發(fā)生阻塞,而synchronized會發(fā)生阻塞。
volatile是變量在多線程之間的可見性,synchronize是多線程之間訪問資源的同步性。
5.synchronized 關(guān)鍵字的底層原理

synchronized 關(guān)鍵字底層原理屬于 JVM 層面。

① synchronized 同步語句塊的情況

public class SynchronizedDemo { public void method() {synchronized (this) { System.out.println("synchronized 代 碼 塊 ");}}
}

通過 JDK 自帶的 javap 命令查看 SynchronizedDemo 類的相關(guān)字節(jié)碼信息:首先切換到類的對應(yīng)目錄執(zhí)行? ? ?javac?SynchronizedDemo.java??命令生成編譯后的 .class 文件,然后執(zhí)行javap -c -s -v -l??SynchronizedDemo.class

(javap 是 Java class文件分解器,可以反編譯,也可以查看 java 編譯器生成的字節(jié)碼等。)

從上面我們可以看出:

synchronized 同步語句塊的實現(xiàn)使用的是 monitorenter monitorexit 指令,其中 monitorenter 指令指向同步代碼塊的開始位置,monitorexit 指令則指明同步代碼塊的結(jié)束位置。 當(dāng)執(zhí)行 monitorenter 指令時,線程試圖獲取鎖也就是獲取 monitor(monitor對象存在于每個Java對象的對象頭中,synchronized 鎖便是通過這種方式獲取鎖的,也是為什么Java中任意對象可以作為鎖的原因) ?????的持有權(quán).當(dāng)計數(shù)器為0則可以成功獲取,獲取后將鎖計數(shù)器設(shè)1也就是加1。相應(yīng)的在執(zhí)行 monitorexit 指令后,將鎖計數(shù)器設(shè)為0,表明鎖被釋放。如果獲取對象鎖失敗,那當(dāng)前線程就要阻塞等待,直到鎖被另外一個線程釋放為止。

?② synchronized 修飾方法的的情況② synchronized 修飾方法的的情況

public class SynchronizedDemo2 { public synchronized void method() {System.out.println("synchronized 方法");}
}

synchronized ?修飾的方法并沒有 ?monitorenter ?指令和 ?monitorexit ?指令,取得代之的確實是ACC_SYNCHRONIZED 標(biāo)識,該標(biāo)識指明了該方法是一個同步方法,JVM 通過該 ACC_SYNCHRONIZED 訪問標(biāo)志來辨別一個方法是否聲明為同步方法,從而執(zhí)行相應(yīng)的同步調(diào)用。

(備注:如果synchronized關(guān)鍵字修飾非靜態(tài)方法且沒有指明具體的鎖對象時,認(rèn)為每次的對象實例就是鎖對象就是每次鎖的對象new不一樣的就不能實現(xiàn)代碼同步。要解決這一問題需要指定鎖對象為class或添加staic關(guān)鍵字或指定鎖對象是同一個對象實例就可以?,如果添加的鎖對象是當(dāng)前實例則每次new對象則產(chǎn)生新的對象實例不能鎖同步)

6.說說 JDK1.6 之后的synchronized 關(guān)鍵字底層做了哪些優(yōu)化,可以詳細(xì)介紹一下這些優(yōu)化嗎

JDK1.6 ???對鎖的實現(xiàn)引入了大量的優(yōu)化,如偏向鎖、輕量級鎖、自旋鎖、適應(yīng)性自旋鎖、鎖消除、鎖粗化等技術(shù)來減少鎖操作的開銷。

鎖主要存在四種狀態(tài),依次是:無鎖狀態(tài)、偏向鎖狀態(tài)、輕量級鎖狀態(tài)、重量級鎖狀態(tài),他們會隨著競爭的激烈而逐 ??漸升級。注意鎖可以升級不可降級,這種策略是為了提高獲得鎖和釋放鎖的效率。

7.synchronized和ReenTrantLock 的區(qū)別

① 兩者都是可重入鎖
兩者都是可重入鎖?!翱芍厝腈i”概念是:自己可以再次獲取自己的內(nèi)部鎖。比如一個線程獲得了某個對象的鎖,此時 ?這個對象鎖還沒有釋放,當(dāng)其再次想要獲取這個對象的鎖的時候還是可以獲取的,如果不可鎖重入的話,就會造成死 ? 鎖。同一個線程每次獲取鎖,鎖的計數(shù)器都自增1,所以要等到鎖的計數(shù)器下降為0時才能釋放鎖。
② synchronized 依賴于 JVM 而 ReenTrantLock 依賴于 API
synchronized 是依賴于 JVM 實現(xiàn)的,前面我們也講到了 虛擬機(jī)團(tuán)隊在 JDK1.6 為 synchronized 關(guān)鍵字進(jìn)行了很多優(yōu)化,但是這些優(yōu)化都是在虛擬機(jī)層面實現(xiàn)的,并沒有直接暴露給我們。ReenTrantLock 是 JDK 層面實現(xiàn)的(也就是 API 層面,需要 lock() 和 unlock 方法配合 try/?nally 語句塊來完成),所以我們可以通過查看它的源代碼,來看它是如何實現(xiàn)的。ReenTrantLock 他是實現(xiàn)lock接口的類
③ ReenTrantLock 比 synchronized 增加了一些高級功能
相比synchronized,ReenTrantLock增加了一些高級功能。主要來說主要有三點:①等待可中斷;②可實現(xiàn)公平鎖;
③可實現(xiàn)選擇性通知(鎖可以綁定多個條件)

ReenTrantLock提供了一種能夠中斷等待鎖的線程的機(jī)制,通過lock.lockInterruptibly()來實現(xiàn)這個機(jī)制。也就是說正在等待的線程可以選擇放棄等待,改為處理其他事情。
ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等 ? ? 待的線程先獲得鎖。 ReenTrantLock默認(rèn)情況是非公平的,可以通過 ReenTrantLock類的ReentrantLock(boolean fair) 構(gòu)造方法來制定是否是公平的。
synchronized關(guān)鍵字與wait()和notify/notifyAll()方法相結(jié)合可以實現(xiàn)等待/通知機(jī)制,ReentrantLock類當(dāng)然也 ?可以實現(xiàn),但是需要借助于Condition接口與newCondition() ?方法。Condition是JDK1.5之后才有的,它具有很好的靈活性,比如可以實現(xiàn)多路通知功能也就是在一個Lock對象中可以創(chuàng)建多個Condition實例(即對象監(jiān)視器),線程對象可以注冊在指定的Condition中,從而可以有選擇性的進(jìn)行線程通知,在調(diào)度線程上更加靈
活。 在使用notify/notifyAll()方法進(jìn)行通知時,被通知的線程是由 JVM 選擇的,用ReentrantLock類結(jié)合Condition實例可以實現(xiàn)“選擇性通知” ,這個功能非常重要,而且是Condition接口默認(rèn)提供的。而synchronized關(guān)鍵字就相當(dāng)于整個Lock對象中只有一個Condition實例,所有的線程都注冊在它一個身上。如果執(zhí)行notifyAll()方法的話就會通知所有處于等待狀態(tài)的線程這樣會造成很大的效率問題,而Condition實例的signalAll()方法 只會喚醒注冊在該Condition實例中的所有等待線程。
如果你想使用上述功能,那么選擇ReenTrantLock是一個不錯的選擇。
④ 性能已不是選擇標(biāo)準(zhǔn)

下面是ReentrantLock的基本使用,先創(chuàng)建一個鎖再釋放鎖 注意鎖釋放一般放在finally代碼塊里防止死鎖??芍厝腈i

public class Test {private static final ReentrantLock lock = new ReentrantLock();public static void main(String[] args){//可重入鎖// 獲取鎖lock.lock();try {System.out.println("main方法中獲取到了鎖..");m1();} catch (Exception e) {e.printStackTrace();} finally {// 釋放鎖lock.unlock();System.out.println("main方法中釋放到了鎖..");}}public static void m1(){lock.lock();try {System.out.println("m1方法中獲取到了鎖..");} catch (Exception e) {e.printStackTrace();} finally {// 釋放鎖lock.unlock();System.out.println("m1方法中釋放了鎖..");}}}

? 上面的代碼和輸入結(jié)果證明,在一個線程中,main方法沒有釋放鎖,m1方法就能獲取到鎖,由此證明了ReentrantLock的可重入性。

可打斷鎖

要想實現(xiàn)可打斷特性,不可以調(diào)用lock()方法,需要調(diào)用 lockInterruptibly() 方法。當(dāng)有線程競爭鎖的時候,某一線程獲取鎖失敗會進(jìn)入休眠狀態(tài),如果加鎖時調(diào)用的是lockInterruptibly() 方法,在其它線程中調(diào)用interrupt方法,該線程會報異常并放棄爭搶鎖,如果加鎖時調(diào)用lock方法,interrupt后依然會繼續(xù)休眠,直到獲取到鎖。

public class ReentranLockDemo {//可重入鎖private static final ReentrantLock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {@SneakyThrows@Overridepublic void run() {dosomething();Thread.currentThread().sleep(100);}}).start();Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {dosomething();}});t2.start();t2.interrupt();//線程沒得到鎖做些別的事情}private static void dosomething(){//獲取鎖try {lock.lockInterruptibly();//可打斷System.out.println(Thread.currentThread().getName()+" 方法中獲取了lock");//m1();//可重入鎖} catch (InterruptedException e) {System.out.println("打斷do other thing");//打斷后可做的事情e.printStackTrace();}finally{try {//釋放鎖lock.unlock();System.out.println(Thread.currentThread().getName() + " 方法中釋放了鎖lock");}catch(Exception e){System.out.println("沒得到鎖的做些別的事情");}}}

公平鎖和非公平鎖

 private static final ReentrantLock lock = new ReentrantLock(true);
//公平鎖

默認(rèn)非公平鎖

對象監(jiān)視器condition使用

在使用 synchronized 的時候,線程的等待是使用 wait()、notify()和 notifyAll() 等方法。而在與 Lock 配合就需要使用到 Condition。從 ReentrantLock 的 newCondition() 方法中獲取一個 Condition 對象。Condition 無法單獨使用,還是需要先獲取到鎖之后再使用。

ReentranLock鎖和condition搭配使用

public class ReentranLockDemo<T>{//可重入鎖private static final ReentrantLock lock = new ReentrantLock(true);private final Condition product = lock.newCondition();//生產(chǎn)者//監(jiān)視器對象private final Condition customer= lock.newCondition();//消費者private final  int MAX = 10; //最多10個元素private int count = 0;//計數(shù)器private final LinkedList<T> lists = new LinkedList<>();private void put(T t){try {lock.lock();//獲取鎖System.out.println(Thread.currentThread().getName()+"生產(chǎn)者獲取鎖");while (lists.size() == MAX) {product.await();System.out.println(Thread.currentThread().getName()+"生產(chǎn)者等待");}lists.add(t);++count;customer.signalAll();//喚醒所有消費者System.out.println(Thread.currentThread().getName()+"通知消費者消費");}catch(InterruptedException e){System.out.println(Thread.currentThread().getName()+"生產(chǎn)者await鎖失敗");}finally{lock.unlock();//釋放鎖System.out.println(Thread.currentThread().getName()+"生產(chǎn)者釋放鎖");}}private T get(){T t = null;try{lock.lock();System.out.println(Thread.currentThread().getName()+"消費者獲取鎖");while(lists.size()==0){customer.await();System.out.println(Thread.currentThread().getName()+"消費者等待");}t=lists.removeFirst();count--;product.signalAll();//通知生產(chǎn)者開始生產(chǎn)System.out.println(Thread.currentThread().getName()+"通知生產(chǎn)者開始生產(chǎn)");} catch (InterruptedException e) {e.printStackTrace();System.out.println(Thread.currentThread().getName()+"消費者await鎖失敗");} finally {lock.unlock();System.out.println(Thread.currentThread().getName()+"消費者釋放鎖");}return t;}public static void main(String[] args) throws InterruptedException {ReentranLockDemo<String> c = new ReentranLockDemo<String>();//啟動消費者線程for(int i=0;i<10;i++){new Thread(()->{while(true){System.out.println("消費產(chǎn)品:"+c.get());}}, "c" + i).start();}//啟動生產(chǎn)者線程AtomicInteger index=new AtomicInteger(0);for(int i=0;i<2;i++){new Thread(()->{while(true){c.put(Thread.currentThread().getName()+" -- "+index.getAndIncrement());}}, "p" + i).start();}}
}

二 關(guān)于線程池的一些問答:

http://m.risenshineclean.com/news/62803.html

相關(guān)文章:

  • 外貿(mào)獨立站搭建東莞seo優(yōu)化推廣
  • 北京 網(wǎng)站 公安備案品牌推廣平臺
  • win7怎么做網(wǎng)站服務(wù)器嗎怎么優(yōu)化網(wǎng)站關(guān)鍵詞排名
  • 哪個公司網(wǎng)站做的好阿拉善盟seo
  • 真正學(xué)做網(wǎng)站要多久北京seo優(yōu)化排名
  • 網(wǎng)站開發(fā)視頻教學(xué)網(wǎng)絡(luò)優(yōu)化推廣公司哪家好
  • 什么專業(yè)學(xué)做網(wǎng)站seo黑帽培訓(xùn)騙局
  • 普陀做網(wǎng)站免費手游推廣平臺
  • 廣州佛山建設(shè)信息網(wǎng)站個人微信管理系統(tǒng)
  • java網(wǎng)站開發(fā)通用框架seo優(yōu)化主要工作內(nèi)容
  • 網(wǎng)站建設(shè)seoppt百度關(guān)鍵詞優(yōu)化多少錢一年
  • 國外免費b2b網(wǎng)站排名互聯(lián)網(wǎng)營銷策略有哪些
  • wordpress 調(diào)用 apigoogleseo優(yōu)化
  • 網(wǎng)站模板與網(wǎng)站開發(fā)電商軟文范例300字
  • 只用ip做網(wǎng)站 不備案市場營銷活動策劃方案
  • 繼電器做網(wǎng)站關(guān)鍵詞排名監(jiān)控
  • 外貿(mào)開發(fā)產(chǎn)品網(wǎng)站建設(shè)時空seo助手
  • 網(wǎng)站建設(shè)運營知乎淮安百度推廣公司
  • 網(wǎng)站建設(shè)注意企業(yè)網(wǎng)站設(shè)計代碼
  • 朝陽做網(wǎng)站的公司杭州百度整站優(yōu)化服務(wù)
  • 石家莊網(wǎng)站建站公司百度廣告位價格
  • 怎樣下載網(wǎng)頁上的視頻如何將網(wǎng)站的關(guān)鍵詞排名優(yōu)化
  • 做網(wǎng)站的書籍推薦網(wǎng)絡(luò)小說網(wǎng)站三巨頭
  • 網(wǎng)站加載特效聊城網(wǎng)站推廣的公司
  • 沙井網(wǎng)站建設(shè)嵌入式培訓(xùn)
  • 以遇見為主題做網(wǎng)站蘇州疫情最新通知
  • 清遠(yuǎn)建網(wǎng)站的公司seo軟文推廣工具
  • 做的網(wǎng)站每年都要交費嗎搜索引擎優(yōu)化
  • 網(wǎng)站精品案例推廣運營是做什么的
  • 漢中網(wǎng)站建設(shè)百度搜索資源平臺token