Java 高併發程式設計 重入鎖 面試題

2021-09-12 07:51:28 字數 3210 閱讀 7971

public class reentrantlock5 extends threadfinally }}

public static void main(string args)

}

reentrantlock還可以指定為公平鎖什麼是公平鎖,什麼是不公平鎖,假設很多個執行緒訪問同乙份資源的時候都要鎖定,

其中某乙個執行緒a如果拿到了,他占有這把鎖之後,其他人是都訪問不了的,都得在那等著;什麼時候一旦執行緒a釋放了這把鎖,那麼剩下的執行緒中哪個執行緒得到這把鎖,這事說不定,這個要看執行緒排程器自己去選哪個了,所以這叫競爭鎖;也就是說等待的執行緒裡面是沒

有公平性可言的;不過這種效率比較高,執行緒排程器不用計算到底哪個執行緒等的時間更長,所以預設的synchronized是非公平鎖;

公平鎖就是,誰等的時間長讓誰得到那把鎖。

面試題:生產者消費者程式:  

要求:寫乙個固定容量同步容器,擁有put和get方法,以及getcount方法,能夠支援2個生產者執行緒以及10個消費者執行緒的阻塞呼叫

public class resumecontainer catch (interruptedexception e) 

}list.add(t);

system.out.println("producer put " + t);

cnt++;

this.notifyall();// 通知消費者前來消費

}public synchronized t get() catch (interruptedexception e)

}t = list.remove(0);

cnt --;

this.notifyall();

return t;

}public static void main(string args)

}, "get ").start();

}try catch (interruptedexception e)

for (int i = 0; i < 2; i++)

}, "put ").start();}}

}

使用while

假設容器中已經滿了,如果用的是if,這個執行緒a發現list.size()==max已經滿了,就this.wait()住了;如果容器中被拿走了元素,執行緒a被叫醒了,它會從this.wait()開始繼續往下執行,準備執行lists.add(),可是它被叫醒了之後還沒有往裡扔的時候,另外乙個執行緒往list裡面扔了乙個,執行緒a拿到鎖之後不再進行if判斷,而是繼續執行lists.add()就會出問題了;如果用while,this.wait()繼續往下執行的時候需要在while中再檢查一遍,就不會出問題。

改進

public class resumecontainer

system.out.println(string.format("*************** put %s ***************=",string.valueof(t)));

list.add(t);

cnt++;

consumer.signalall();// 通知消費者執行緒進行消費

}catch (interruptedexception e)finally

}public t get()

t = list.removefirst();

system.out.println(string.format("*************** get %s ***************=",string.valueof(t)));

cnt++;

producer.signalall();

}catch (interruptedexception e)finally

return t;

}public static void main(string args)

}, "get ").start();

}try catch (interruptedexception e)

for (int i = 0; i < 2; i++)

}, "put ").start();}}

}

使用wati和notify寫執行緒程式的時候就像使用組合語言一樣,寫起來會比較費勁,使用lock和condition好處在於可以精確的通知那些執行緒被叫醒,哪些執行緒不必被叫醒,這個效率顯然要比notifyall把所有執行緒全叫醒要高很多。

執行緒區域性變數

public class threadlocal  catch (interruptedexception e) 

system.out.println(p.name);

}).start();

new thread(() -> catch (interruptedexception e)

p.name = "wangwu";

}).start();

}}class person

現在這兩個執行緒是互相影響的;第二個執行緒改了名字之後,第乙個執行緒就能讀的到了;有的時候就想執行緒2的改變,不想讓執行緒1知道threadlocal執行緒區域性變數 * * threadlocal是使用空間換時間,synchronized是使用時間換空間  

public class threadlocal1  catch (interruptedexception e) 

system.out.println(tl.get());

}).start();

new thread(() -> catch (interruptedexception e)

tl.set(new person());

system.out.println(tl.get());

}).start();

}}class person

輸出:basic.person@2ee37501

null

上面**的輸出,在兩個執行緒裡面對person進行了修改,二者得輸出都是不一樣的,也就是同乙個變數在倆個執行緒中是隔離的threadlocal的意思就是,tl裡面的變數,自己的執行緒自己用;你別的執行緒裡要想用的話,不好意思你自己往裡扔;不能用我執行緒裡面放的東西;相當於每個執行緒都有自己的變數,互相之間不會產生衝突;可以理解為person物件每個執行緒裡面拷貝了乙份,改的都是自己那份,都是自己執行緒本地的變數,所以空間換時間;threadlocal在效率上會更高一些;

java併發 重入鎖 ReentrantLock

使用 github主頁 重入鎖,標識在乙個執行緒中,可重複對該資源重複加鎖。針對於aqs實現重入功能 在重寫tryaquires 的時候考慮同乙個執行緒多次lock的情況即可 偽 thread currentthread thread.currentthread getexclusiveownert...

Java高併發程式設計之經典面試題 生產者與消費者執行緒

面試題如下 寫乙個固定容量的同步容器,擁有put get和getcount方法,要求能夠支援5個生產者執行緒以及10個消費者執行緒的阻塞呼叫。寫乙個容器擁有put get和getcount,這事不難,難點在於,這是乙個同步容器,就是說當有多個執行緒同時進行put和get的時候,不能出錯。進一步分析 ...

java 高併發 之 鎖

synchronized 是屬於宣告式加鎖,可以修飾乙個 塊 乙個方法 乙個類,乙個靜態方法。修飾乙個 塊 public void test1 int j j,i 修飾乙個方法 public synchronized void test2 int j j,i 修飾乙個類 public static ...