<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小菜毛毛技術(shù)分享

    與大家共同成長

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

    早早就聽說過開發(fā)方向的筆試面試都是以算法和數(shù)據(jù)結(jié)構(gòu)這些基礎(chǔ)為主,我自恃著那么一丁點項目經(jīng)驗,一直沒放在心上。

    連日下來的筆試徹底印證了師兄們的話,筆試基本不過。最可惜的是淘寶,筆試中發(fā)揮不錯終于能進一面,一開始聊家常聊框架聊開源技術(shù)還聊得不錯,突然 間,連續(xù)問了三個問題:

    1.多線程訪問hashtable和hashmap有什么不一樣?我只答出線程安全不一樣,具體怎么不一樣就有一句每一句了(回來google一 下,這種java基礎(chǔ)還真TM簡單,枉稱精通java了)

    2.平衡二叉樹查找算法的復(fù)雜度?再次雷響,隨便蒙了個歸并排序的復(fù)雜度給他。

    3.對于100W條數(shù)據(jù)的排序和查找有什么效率高的方式?完了,結(jié)結(jié)巴巴的說一通,最后自認不會……

    原本以為技術(shù)面會比筆試好過的,回學(xué)校的路上我淚流滿面啊我。這些都不是RP問題了,鐵了心惡補數(shù)據(jù)結(jié)構(gòu)……

    Java線 程安全同步解決方案 

    1、 問題描述:

      如果一個資源或?qū)ο罂赡鼙欢鄠€線程同時訪問,它就是一個共享資源;例如 類的成員變量,包括類變量和實例變量,再比如對一個文件進行寫操作等。一般情況下,對共享資源的訪問需要考慮線程安全的問題。

      如果一個對象的完整生命周期只在一個線程內(nèi),則不需要考慮線程安全,例 如一個局部變量。下面為一個示例代碼:

    1. public class C1 {
    2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
    3. //其他代碼
    4. }

      假如在一個JSP中這樣的去調(diào)用:

    1. <a.jsp>:
    2. <%
    3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
    4. %>

      則這樣的代碼不是線程安全的。因為java.text.SimpleDateFormat 不是線程安全的,a.jsp中的代碼將會有若干個線程同時執(zhí)行,而都訪問的是同一個線程不安全的對象,這樣就不是一個線程安全的代碼。正確的寫法應(yīng)該如 下:

    1. <a.jsp>:
    2. <%
    3. java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
    4. Java.util.Date date = sdf.parse(“2003-4-15”);
    5. %>

    2、 原因分析:

      此時,sdf對象從創(chuàng)建到銷毀都位于一個方法中,相當(dāng)于一個局部變量,不是一個共享資源,因此則沒有線程不安全的問題。

    3、 解決方法或過程:

    1) 如果對象是immutable,則是線程安全的,例如:String,可以放心使用。
    2) 如果對象是線程安全的,則放心使用
    3) 有 條件線程安全,對于Vector和Hashtable一般情況下是線程安全的,但是對于某些特殊情況,需要通過額外的synchronized保證線程安 全。
    4) 使用synchronized關(guān)鍵字;

      對于上例中可以改寫jsp代碼,在sdf上進行同步,而不需要每次創(chuàng)建一個新的對象來保證線程安全,代碼如下:

    1. <%
    2. synchronized(C1.sdf){
    3. Java.util.Date date = C1.sdf.parse(“2003-4-15”);
    4. }
    5. %>

      這種寫法是在一個對象級別上進行同步,也就是說任何時候,對于這個對象,最多只能有一個線程在執(zhí)行同步方法。

      另外一種寫法是在Class級別上進行同步,寫法如下:

    1. public class C1 {
    2. public static java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
    3. public void method(){
    4. synchronized(C1.class){
    5. //synchronized code
    6. }
    7. }
    8. }

      這種寫法表示無論C1有多少個實例,在任何一個時間點,最多只能有一個線程和一個實例進入同步塊中。這種同步會比較大的影響性能。

      5) 有些對象不能在多線程間共享,則只能在方法內(nèi)部使用,或者只在一個線程內(nèi)部使用。

    synchronized詳解

    Java對多線程的支持與同步機制深受大家的喜愛,似乎看起來使用了synchronized關(guān)鍵字就可以輕松地解決多線程共享數(shù)據(jù)同步問題。到底如何?――還得對synchronized關(guān)鍵字的作用進行深入了解才可定論。

    總的說來,synchronized關(guān)鍵字可以作為函數(shù)的修飾符,也可作為函數(shù)內(nèi)的語句,也就是平時說的同步方法和同步語句塊。如果再細的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數(shù)和class literals(類名稱字面常量)身上。

    在進一步闡述之前,我們需要明確幾點:

    A.無論synchronized關(guān)鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數(shù)當(dāng)作鎖――而且同步方法很可能還會被其他線程的對象訪問。

    B.每個對象只有一個鎖(lock)與之相關(guān)聯(lián)。

    C.實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能 造成死鎖,所以盡量避免無謂的同步控制。

    接著來討論synchronized

    用到不同地方對代碼產(chǎn)生的影響:

    假設(shè)P1P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1P2就都可以調(diào)用它們。

    1. synchronized當(dāng)作函數(shù)修飾符時,示例代碼如下:

    Public synchronized void methodAAA()

    {

    //….

    }

    這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調(diào)用這個同步方法對象。也就是說,當(dāng)一個對象P1在不 同的線程中執(zhí)行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所 產(chǎn)生的另一對象P2卻可以任意調(diào)用這個被加了synchronized關(guān)鍵字的方法。

    上邊的示例代碼等同于如下代碼:

    public void methodAAA()

    {

    synchronized (this)      // (1)

    {

           //…..

    }

    }

     (1)處 的this指的是什么呢?它指的就是調(diào)用這個方法的對象,如P1。可見 同步方法實質(zhì)是將synchronized作用于object reference。――那個拿到了P1對象 鎖的線程,才可以調(diào)用P1的同步方法,而對P2而 言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數(shù)據(jù)混亂:(

    2.同步塊,示例代碼如下:

               public void method3(SomeObject so)

                  {

                         synchronized(so)

    {

           //…..

    }

    }

    這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當(dāng)有一個明確的對象作為鎖時,就可以這樣寫程序,但當(dāng)沒有明確的對象作為 鎖,只是想讓一段代碼同步時,可以創(chuàng)建一個特殊的instance變量(它得是一個對象)來充當(dāng)鎖:

    class Foo implements Runnable

    {

           private byte[] lock = new byte[0]; // 特殊的instance變量

        Public void methodA()

    {

           synchronized(lock) { //… }

    }

    //…..

    }

    注:零長度的byte數(shù) 組對象創(chuàng)建起來將比任何對象都經(jīng)濟――查看編譯后的字節(jié)碼:生成零長度的byte[]對 象只需3條操作碼,而Object lock = new Object()則 需要7行操作碼。

    3.將synchronized作用于static 函數(shù),示例代碼如下:

          Class Foo

    {

    public synchronized static void methodAAA()   // 同步的static 函數(shù)

    {

    //….

    }

    public void methodBBB()

    {

           synchronized(Foo.class)   // class literal(類名稱字面常量)

    }

           }

       代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函 數(shù)產(chǎn)生的效果是一樣的,取得的鎖很特別,是當(dāng)前調(diào)用這個方法的對象所屬的類(Class, 而不再是由這個Class產(chǎn)生的某個具體對象了)。

    記得在《Effective Java》一書中看到過將 Foo.class P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來達到鎖這個Class的目的。P1指的是由Foo類產(chǎn)生的對象。

    可以推斷:如果一個類中定義了一個synchronizedstatic函數(shù)A,也定 義了一個synchronized instance函數(shù)B,那么這個類的同一對象Obj在多線程中分別訪問AB兩個方法時,不會構(gòu)成同步,因為它們的鎖都不一樣。A方法的鎖 是Obj這個對象,而B的鎖是Obj所屬的那個Class

    小結(jié)如下:

    搞清楚synchronized鎖定的是哪個對象,就能幫助我們設(shè)計更安全的多線程程序。

    還有一些技巧可以讓我們對共享資源的同步訪問更加安全:

    1. 定義private instance變量+它的 get方法,而不要定義public/protectedinstance變量。如果將變量定義為public,對象在外界可以繞過同步方法的控制而 直接取得它,并改動它。這也是JavaBean的標準實現(xiàn)方式之一。

    2. 如果instance變量是一個對象,如數(shù)組或ArrayList什么的,那上述方法仍然不安全, 因為當(dāng)外界對象通過get方法拿到這個instance對象的引用后,又將其指向另一個對象,那么這個private變量也就變了,豈不是很危險。這個時候就需要將get方法 也加上synchronized同步,并且,只返回這個private對象的clone()――這樣,調(diào)用端得到的就是對象副本的引用了。



    posted on 2010-05-11 09:49 小菜毛毛 閱讀(915) 評論(0)  編輯  收藏 所屬分類: 面試
    主站蜘蛛池模板: jzzjzz免费观看大片免费| 亚洲精品人成网线在线播放va| 亚洲日韩在线观看免费视频| 日本中文一区二区三区亚洲| 边摸边吃奶边做爽免费视频99| 免费国产成人高清视频网站| 免费看一级毛片在线观看精品视频| 波多野结衣一区二区免费视频| 黄色大片免费网站| 亚洲色欲久久久久综合网| 久久精品成人免费观看97| 亚洲国产精品国自产拍AV| 99精品视频免费观看| 亚洲综合久久一本伊伊区| 毛片网站免费在线观看| 国产偷国产偷亚洲高清人| 亚洲精品美女久久久久99小说| a级黄色毛片免费播放视频| 久久精品蜜芽亚洲国产AV| 一个人看的www在线观看免费| 亚洲精品天堂成人片AV在线播放| 亚洲AV蜜桃永久无码精品| 两个人看的www免费视频| 亚洲视频在线观看地址| 国产成人精品免费视频软件| 一个人看的www免费在线视频| 亚洲AV无码专区国产乱码4SE| 成人无码区免费A片视频WWW| 偷自拍亚洲视频在线观看| 亚洲国产精品无码专区在线观看| 免费在线视频你懂的| 相泽南亚洲一区二区在线播放| 亚洲综合熟女久久久30p| 久久w5ww成w人免费| 亚洲av无码专区亚洲av不卡| 一本久久a久久精品亚洲| 欧美a级成人网站免费| 中文字幕免费播放| 亚洲国产综合精品中文第一| 亚洲日本中文字幕天堂网| 无码人妻久久一区二区三区免费丨 |