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

2021-08-31 20:58:11 字數 1874 閱讀 4772

面試題如下:

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

寫乙個容器擁有put、get和getcount,這事不難,難點在於,這是乙個同步容器,就是說當有多個執行緒同時進行put和get的時候,不能出錯。

進一步分析:

1、如果容器為空,那麼呼叫get方法的執行緒(消費者)需要等待(wait)

2、如果容器已滿,那麼呼叫put方法的執行緒(生產者)需要等待(wait)

3、當容器不為空,通知所有消費者進行get操作(notify/notifyall)

4、當容器還未滿,通知所有生產者進行put操作(notify/notifyall)

5、多生產與多消費者之間需要同步呼叫(synchronized)

實現這個阻塞式的同步容器,首先想到的是、使用synchronized和wait、notify/notifyall結合實現同步和執行緒間通訊。

分析了思路後,實現起來其實非常簡單,**如下:

public class mycontainer1 catch (interruptedexception e) 

}lists.add(t);

++count;

system.out.println(thread.currentthread().getname() + "進行生產了,當前剩餘:" + getcount());

//通知所有消費者執行緒進行消費

this.notifyall();

}/**

* get 方法

* @return

*/public synchronized t get() catch (interruptedexception e)

}t t = lists.removelast();

--count;

system.out.println(thread.currentthread().getname() + "進行消費了,當前剩餘:" + getcount());

//通知所有生產者執行緒

this.notifyall();

return t;

}/**

* getcount方法

* @return

*/public synchronized int getcount()

public static void main(string args) catch (interruptedexception e)

}}, "p_thread_" + i).start();

}for(int i = 1; i <= 10; i++) catch (interruptedexception e)

}}, "c_thread_" + i).start();}}

}

有個小陷阱需要特別注意,put和get方法裡面判斷容器容量的時候用的while而不是if,這是為什麼呢?

假如現在用的是if,某個時刻出現如下狀況:

1、容器已滿

2、5個生產者執行緒輪流執行put方法,if語句判斷容器已滿,5個生產者依次進入wait轉態

3、接著某個消費者執行緒執行了get方法,並喚醒所有wait狀態的生產者執行緒

4、所有生產者執行緒依次執行wait後面的語句,即lists.add(t)++count;

問題出在第4步,因為用的是if,所以每個執行緒都不會再次進行判斷就執行wait後面的語句了,這就將導致容器溢位!get方法也是同樣的道理。

記住這個比較高階的程式設計技巧:用到wait的時候,99.9%的情況下,都需要同while一起使用。

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

public class reentrantlock5 extends threadfinally public static void main string args reentrantlock還可以指定為公平鎖什麼是公平鎖,什麼是不公平鎖,假設很多個執行緒訪問同乙份資源的時候都要鎖定,其中某乙...

經典JAVA面試題

建立 tcp ip 連線 三次握手具體過程 由瀏覽器傳送乙個 http 請求 經過路由器的 通過伺服器的防火牆,該 http 請求到達了伺服器 伺服器處理該 http 請求,返回乙個 html 檔案 瀏覽器解析該 html 檔案,並且顯示在瀏覽器端 這裡需要注意 2.事務的併發問題有哪幾種?答 丟失...

java經典面試題

string str abcdesjkjsadfoiqwejhjkahjsiuhaskhka int counter new int 26 for int i 0 i經典面試題目 int n 5 for int i 0 i 5 i system.out.println n 5解析 n 5 n n 規...