標籤:摩根斯坦利 大摩 面試 多線程 blockingqueue
今天上午,參加大摩的面試,自覺失敗,記錄一下過程。
面試官看著簡曆,並沒有就簡曆提問,整個過程都在問java多線程的問題。
1. ReentrantLock,作為可重新進入鎖,怎麼理解“可重新進入”二字,有沒有不可重複的鎖?
我:獲得對象鎖的線程能夠再次獲得對象鎖,訪問對象……被鄙視了,後來想想,應該把遞迴這種情境說下;
2.生產者-消費者模型怎麼實現?
我:使用synchronized或者Lock這些同步方法實現。
面試官就問,為什麼不用一些更進階的封裝呢?
我:可以使用Exchanger類。
面試官:用BlockingQueue也可以,接下來,
3.作為一個介面,它有哪些具體的實作類別?如何?一個BlockingQueue,請實現它?
我:不清楚具體實現(後來查了下,有ArrayBlockingQueue,LinkedBlocking,PriorityBlockingQueue,DelayQueue,SynchronousQueue,前兩個最常見)。
可以使用List來儲存資料,使用Lock與Condition來保證同步,代碼如下(最好使用模板),
public class DefinedBlockingQueue {private LinkedList<Integer> queue;private Lock lock;private int max;private Condition empty;private Condition full;public DefinedBlockingQueue(LinkedList<Integer> queue, int max) {this.queue = queue;this.max = max;lock = new ReentrantLock();full = lock.newCondition();empty = lock.newCondition();}public Integer take() {lock.lock();Integer t = null;try {while (queue.isEmpty()) {full.await();}t = queue.poll();empty.signalAll();return t;} catch (InterruptedException e) {// e應該做處理} finally {lock.unlock();}return t;}public void put(Integer e) {lock.lock();try {while (queue.size() == max) {empty.await();}queue.add(e);full.signalAll();} catch (InterruptedException e) {// e應該做處理} finally {lock.unlock();}}}
4. 為什麼使用Condition和Lock而不是synchronized和wait()來實現BlockingQueue()?
我:前者具有更好的特性,比如tryLock、讀寫鎖等。
後來我又查了資料,補充:
Lock介面支援更靈活的同步代碼塊結構:使用synchronized關鍵字時,只能在同一個synchronized塊結構中擷取和釋放控制。Lock介面允許實現更複雜的臨界區結構(控制的擷取和釋放不出現在同一個塊結構中),比如ArrayBlockingQueue類的
void removeAt(int i) { final Object[] items = this.items; // if removing front item, just advance if (i == takeIndex) { items[takeIndex] = null; takeIndex = inc(takeIndex); } else { // slide over all others up through putIndex. for (;;) { int nexti = inc(i); if (nexti != putIndex) { items[i] = items[nexti]; i = nexti; } else { items[i] = null; putIndex = i; break; } } } --count; notFull.signal(); }
摩根斯坦利面試——Java多線程