日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java-多线程-一道阿里面试题分析

發布時間:2023/11/29 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java-多线程-一道阿里面试题分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

傳說這是阿里的一道面試題: 也傳說發這道題出來的作者去了tmail。下面是關于題目的描述:

? ? ?這段代碼大多數情況下運行正常,但是某些情況下會出問題。什么時候會出現什么問題?如何修正?可見博客?http://yueyemaitian.iteye.com/blog/1387901?

Java代碼??
  • public?class?MyStack?{??
  • ????private?List<String>?list?=?new?ArrayList<String>();??
  • ??
  • ????public?synchronized?void?push(String?value)?{??
  • ????????synchronized?(this)?{??
  • ????????????list.add(value);??
  • ????????????notify();??
  • ????????}??
  • ????}??
  • ??
  • ????public?synchronized?String?pop()?throws?InterruptedException?{??
  • ????????synchronized?(this)?{??
  • ????????????if?(list.size()?<=?0)?{??
  • ????????????????wait();??
  • ????????????}??
  • ????????????return?list.remove(list.size()?-?1);??
  • ????????}??
  • ????}??
  • } ?

  • 下面是關于這道題的分析:

    ? ?list.remove(list.size() - 1);這句代碼有可能引發數組下標越界
    原因:
    假設其中一種情形呵!出問題的情形可能很多,但原理都差不多。下面的標號代表程序時序的先后順序。
    ?1,初始化時list的值為0,然后線程1調用了pop,于是被wait了,然后釋放了鎖。
    ?2,線程2調用push,在notify之前有線程3調用pop(記住這時候線程1還沒有被喚醒,還在wait住),此時線程3會因為等待鎖而掛起,或自旋,反正就是在等待鎖可用。
    ?3,然后線程2繼續往下執行,notify被執行(但這時候線程1是不會喚醒的,因為鎖還在線程2占用),線程2退出push方法,釋放內置鎖,此時,線程1和線程3都在內置鎖等待隊列里面。由于synchronized是沒法保證線程競爭的公平性,所以線程1和線程3都可能得到鎖。
    ?4,假設線程1競爭到了鎖,不會出問題,正常去除list值,然后remove,執行完后線程3執行,同樣被wait住。
    ?5,假設線程3競爭到了鎖,問題來了,線程3會判斷到list的size不為0,于是remove,所以list的size就為0了,然后線程 3釋放鎖,這時候,線程1就得到鎖,于是從wait中醒來,繼續執行,然后直接調用list的remove,由于list的size=0,那么remove(-1),越界錯誤就產生了。


    ? ?還有同學說兩個線程都在wait處等候也會出問題,其實不會出問題的,因為是調用的notify而不是notifyAll,如果是調用notifyAll那么也會出同樣的問題。


    ? 至于改進:
    ? 看到這個題目我就很納悶,為什么要用雙重鎖,好像沒有必要雙重鎖。我第一眼看到雙重鎖的時候就在想,出題者是不是在模擬一個套管死鎖,我也確實為找這個死鎖付出了一些時間。但是這個雙重檢查都是可重入的鎖,都是對于this對象上的鎖。所以不存在套管死鎖。 改進1,——最小代碼改動,就在remove之前再檢查list.size==0 改進2,——去掉push和pop方法內的第二重鎖檢查,我確實沒有發現這個鎖會有什么用,反而耗性能。 當然這里還是要有方案1的判斷(謝謝一樓提醒)。 改進3,——重新設計,如果是我來設計這么一個生產者,消費者模式。我更愿意用LinkedBlockingQueue,它有take方法阻塞消費者直到隊列可用。而且還有offer方法阻塞生產者直到隊列可以插入,可以有效的阻止OOM。
    ? 這個題目出的好,難道是阿里有人犯過這個錯誤!呵呵!
    ? 關于本題的討論如有任何紕漏,請大家及時指出呵!

    轉載于:https://my.oschina.net/u/176507/blog/137880

    總結

    以上是生活随笔為你收集整理的java-多线程-一道阿里面试题分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。