java面經查缺補漏之三十九天(繼續努力)

1.什麼時候用原子操作類,舉個例子?

比如一個自增的操作就可以用原則操作類,原子操作類底層用的就是CAS。

2.什麼時候用volitile,舉個例子?

比如一個boolean的flag,因爲它與上個狀態無關。

3.手寫程序,10個多線程保證 i從0加到10?

可以用原子操作類來實現

import java.util.concurrent.atomic.AtomicInteger;

public class Autoincrease {
    public static void main(String[] args)
    {
        atomicThread matomicThread=new atomicThread();
        for(int i=0;i<10;i++)
        {
            Thread thread=new Thread(matomicThread);
            thread.start();
        }
    }
    public static class atomicThread implements Runnable
    {
        public AtomicInteger i=new AtomicInteger();
        @Override
        public void run() {
            while(true)
            {
                try {
                    Thread.sleep(1000);
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
                System.out.println("線程: " + Thread.currentThread().getName() + "將數據變爲: " + i.getAndIncrement());
            }
        }
    }
}

4.如何避免死鎖?

主要有三種方式:

參考:https://blog.csdn.net/ls5718/article/details/51896159?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-4

這篇文章對於死鎖的講解還是不錯的

(1)加鎖順序

當多個線程需要相同的一些鎖,但是按照不同的順序加鎖,死鎖就很容易發生。

比如線程一lockA lockB線程二lockB lockA那麼線程一佔有A管線程二要B,但此時線程二佔有B,它又去管線程一要A,這樣就造成了死鎖。如果要是都是一樣的順序的話,那麼就可以避免死鎖了。

按照順序加鎖是一種有效的死鎖預防機制。但是,這種方式需要你事先知道所有可能會用到的鎖(譯者注:並對這些鎖做適當的排序),但總有些時候是無法預知的。

(2)加鎖時限

超時自動釋放鎖,就算髮生死鎖了,也會自動解開。

這種機制存在一個問題,在Java中不能對synchronized同步塊設置超時時間。你需要創建一個自定義鎖,或使用Java5中java.util.concurrent包下的工具。寫一個自定義鎖類不復雜,

(3)死鎖檢測

死鎖檢測是一個更好的死鎖預防機制,它主要是針對那些不可能實現按序加鎖並且鎖超時也不可行的場景。

當發現死鎖的時候,一個可行的做法是釋放所有鎖,回退,並且等待一段隨機的時間後重試。一個更好的方案是給這些線程設置優先級,讓一個(或幾個)線程回退,剩下的線程就像沒發生死鎖一樣繼續保持着它們需要的鎖。

5.公平鎖與非公平鎖的區別?

tryAcquire是公平鎖和非公平鎖實現的區別,兩種類型的鎖都是tryAcquire實現的。每一次的tryAcquire都會檢查隊列中是否仍有前驅的元素,如果仍然有那麼繼續等待,通過這種方式來保證先來先服務的原則;而非公平鎖,首先是檢查並設置鎖的狀態,這種方式會出現即使隊列中有等待的線程,但是新的線程仍然會與排隊線程中的對頭線程競爭(但是排隊的線程是先來先服務的),所以新的線程可能會搶佔已經在排隊的線程的鎖,這樣就無法保證先來先服務,但是已經等待的線程們是仍然保證先來先服務的。

公平鎖能保證:老的線程排隊使用鎖,新線程仍然排隊使用鎖。

非公平鎖保證:老的線程排隊使用鎖;但是無法保證新線程搶佔已經在排隊的線程的鎖。

6.synchronized與Lock的區別?

synchronized是一個關鍵字,可重入,不可判斷鎖的狀態,非公平,自動釋放鎖。

Lock是一個類,可重入,可判斷鎖的狀態,可公平也可非公平(默認非公平,可構造的時候在ReentrantLock中加入true參數),必須主動釋放鎖。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章