Java 骞跺彂锛氬唴缃攣 Synchronized

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 骞跺彂锛氬唴缃攣 Synchronized相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/code' title='code'>code   string   涓€鍙ヨ瘽   浣跨敤鍦烘櫙   绯荤粺   鍙傛暟   鐜拌薄   瀹冪殑   

鍦ㄥ绾跨▼缂栫▼涓紝绾跨▼瀹夊叏闂鏄竴涓渶涓哄叧閿殑闂锛屽叾鏍稿績姒傚康灏卞湪浜庢纭€э紝鍗冲綋澶氫釜绾跨▼璁块棶鏌愪竴鍏变韩銆佸彲鍙樻暟鎹椂锛屽缁堥兘涓嶄細瀵艰嚧鏁版嵁鐮村潖浠ュ強鍏朵粬涓嶈鍑虹幇鐨勭粨鏋溿€傝€屾墍鏈夌殑骞跺彂妯″紡鍦ㄨВ鍐宠繖涓棶棰樻椂锛岄噰鐢ㄧ殑鏂规閮芥槸搴忓垪鍖栬闂复鐣岃祫婧?銆傚湪 Java 涓紝鎻愪緵浜嗕袱绉嶆柟寮忔潵瀹炵幇鍚屾浜掓枼璁块棶锛歴ynchronized 鍜?Lock銆傛湰鏂囬拡瀵?synchronized 鍐呯疆閿?璇︾粏璁ㄨ浜嗗叾鍦?Java 骞跺彂 涓殑搴旂敤锛屽寘鎷畠鐨勫叿浣撲娇鐢ㄥ満鏅紙鍚屾鏂规硶銆佸悓姝ヤ唬鐮佸潡銆佸疄渚嬪璞¢攣 鍜?Class 瀵硅薄閿侊級銆佸彲閲嶅叆鎬?鍜?娉ㄦ剰浜嬮」銆?/p>

涓€. 绾跨▼瀹夊叏闂

銆€銆€鍦ㄥ崟绾跨▼涓笉浼氬嚭鐜扮嚎绋嬪畨鍏ㄩ棶棰橈紝鑰屽湪澶氱嚎绋嬬紪绋嬩腑锛屾湁鍙兘浼氬嚭鐜板悓鏃惰闂悓涓€涓?鍏变韩銆佸彲鍙樿祫婧?鐨勬儏鍐碉紝杩欑璧勬簮鍙互鏄細涓€涓彉閲忋€佷竴涓璞°€佷竴涓枃浠剁瓑銆傜壒鍒敞鎰忎袱鐐癸紝

  • 鍏变韩锛?鎰忓懗鐫€璇ヨ祫婧愬彲浠ョ敱澶氫釜绾跨▼鍚屾椂璁块棶锛?/li>
  • 鍙彉锛?鎰忓懗鐫€璇ヨ祫婧愬彲浠ュ湪鍏剁敓鍛藉懆鏈熷唴琚慨鏀广€?/li>

銆€鎵€浠ワ紝褰撳涓嚎绋嬪悓鏃惰闂繖绉嶈祫婧愮殑鏃跺€欙紝灏变細瀛樺湪涓€涓棶棰橈細

銆€銆€銆€鐢变簬姣忎釜绾跨▼鎵ц鐨勮繃绋嬫槸涓嶅彲鎺х殑锛屾墍浠ラ渶瑕侀噰鐢ㄥ悓姝ユ満鍒舵潵鍗忓悓瀵瑰璞″彲鍙樼姸鎬佺殑璁块棶銆?

涓句釜 鏁版嵁鑴忚 鐨勪緥瀛愶細

//璧勬簮绫?/span>
class PublicVar 

    public String username = "A";
    public String password = "AA";

    //鍚屾瀹炰緥鏂规硶
    public synchronized void setValue(String username, String password) 
        try 
            this.username = username;
            Thread.sleep(5000);
            this.password = password;

            System.out.println("method=setValue " +"\t" + "threadName="
                    + Thread.currentThread().getName() + "\t" + "username="
                    + username + ", password=" + password);
         catch (InterruptedException e) 
            e.printStackTrace();
        
    

    //闈炲悓姝ュ疄渚嬫柟娉?/span>
    public void getValue() 
        System.out.println("method=getValue " + "\t" +  "threadName="
                + Thread.currentThread().getName()+ "\t" + " username=" + username
                + ", password=" + password);
    



//绾跨▼绫?/span>
class ThreadA extends Thread 

    private PublicVar publicVar;

    public ThreadA(PublicVar publicVar) 
        super();
        this.publicVar = publicVar;
    

    @Override
    public void run() 
        super.run();
        publicVar.setValue("B", "BB");
    



//娴嬭瘯绫?/span>
public class Test 

    public static void main(String[] args) 
        try 
            //涓寸晫璧勬簮
            PublicVar publicVarRef = new PublicVar();

            //鍒涘缓骞跺惎鍔ㄧ嚎绋?/span>
            ThreadA thread = new ThreadA(publicVarRef);
            thread.start();

            Thread.sleep(200);// 鎵撳嵃缁撴灉鍙楁鍊煎ぇ灏忓奖鍝?

            //鍦ㄤ富绾跨▼涓皟鐢?/span>
            publicVarRef.getValue();

         catch (InterruptedException e) 
            e.printStackTrace();
        
    
/* Output ( 鏁版嵁浜ゅ弶 ): 
        method=getValue     threadName=main         username=B, password=AA
        method=setValue     threadName=Thread-0     username=B, password=BB
 */

銆€鐢辩▼搴忚緭鍑哄彲鐭ワ紝铏界劧鍦ㄥ啓鎿嶄綔杩涜浜嗗悓姝ワ紝浣嗗湪璇绘搷浣滀笂浠嶇劧鏈夊彲鑳藉嚭鐜颁竴浜涙剰鎯充笉鍒扮殑鎯呭喌锛屼緥濡備笂闈㈡墍绀虹殑 鑴忚銆傚彂鐢?鑴忚 鐨勬儏鍐垫槸鍦ㄦ墽琛岃鎿嶄綔鏃讹紝鐩稿簲鐨勬暟鎹凡琚叾浠栫嚎绋?閮ㄥ垎淇敼 杩囷紝瀵艰嚧 鏁版嵁浜ゅ弶 鐨勭幇璞′骇鐢熴€?/p>

銆€銆€杩欏叾瀹炲氨鏄竴涓嚎绋嬪畨鍏ㄩ棶棰橈紝鍗冲涓嚎绋嬪悓鏃惰闂竴涓祫婧愭椂锛屼細瀵艰嚧绋嬪簭杩愯缁撴灉骞朵笉鏄兂鐪嬪埌鐨勭粨鏋溿€傝繖閲岄潰锛岃繖涓祫婧愯绉颁负锛氫复鐣岃祫婧愩€備篃灏辨槸璇达紝褰撳涓嚎绋嬪悓鏃惰闂复鐣岃祫婧愶紙涓€涓璞★紝瀵硅薄涓殑灞炴€э紝涓€涓枃浠讹紝涓€涓暟鎹簱绛夛級鏃讹紝灏卞彲鑳戒細浜х敓绾跨▼瀹夊叏闂銆?/p>

銆€銆€涓嶈繃锛屽綋澶氫釜绾跨▼鎵ц涓€涓柟娉曟椂锛岃鏂规硶鍐呴儴鐨勫眬閮ㄥ彉閲忓苟涓嶆槸涓寸晫璧勬簮锛屽洜涓鸿繖浜涘眬閮ㄥ彉閲忔槸鍦ㄦ瘡涓嚎绋嬬殑绉佹湁鏍堜腑锛屽洜姝や笉鍏锋湁鍏变韩鎬э紝涓嶄細瀵艰嚧绾跨▼瀹夊叏闂銆?/p>

浜? 濡備綍瑙e喅绾跨▼瀹夊叏闂

銆€銆€瀹為檯涓婏紝鎵€鏈夌殑骞跺彂妯″紡鍦ㄨВ鍐崇嚎绋嬪畨鍏ㄩ棶棰樻椂锛岄噰鐢ㄧ殑鏂规閮芥槸 搴忓垪鍖栬闂复鐣岃祫婧?銆傚嵆鍦ㄥ悓涓€鏃跺埢锛屽彧鑳芥湁涓€涓嚎绋嬭闂复鐣岃祫婧愶紝涔熺О浣?鍚屾浜掓枼璁块棶銆傛崲鍙ヨ瘽璇达紝灏辨槸鍦ㄨ闂复鐣岃祫婧愮殑浠g爜鍓嶉潰鍔犱笂涓€涓攣锛屽綋璁块棶瀹屼复鐣岃祫婧愬悗閲婃斁閿侊紝璁╁叾浠栫嚎绋嬬户缁闂€?/p>

銆€銆€鍦?Java 涓紝鎻愪緵浜嗕袱绉嶆柟寮忔潵瀹炵幇鍚屾浜掓枼璁块棶锛歴ynchronized 鍜?Lock銆傛湰鏂囦富瑕佽杩?synchronized 鐨勪娇鐢ㄦ柟娉?

涓? synchronized 鍚屾鏂规硶鎴栬€呭悓姝ュ潡

銆€銆€鍦ㄤ簡瑙?synchronized 鍏抽敭瀛楃殑浣跨敤鏂规硶涔嬪墠锛屾垜浠厛鏉ョ湅涓€涓蹇碉細浜掓枼閿侊紝鍗?鑳藉埌杈惧埌浜掓枼璁块棶鐩殑鐨勯攣銆備妇涓畝鍗曠殑渚嬪瓙锛屽鏋滃涓寸晫璧勬簮鍔犱笂浜掓枼閿侊紝褰撲竴涓嚎绋嬪湪璁块棶璇ヤ复鐣岃祫婧愭椂锛屽叾浠栫嚎绋嬩究鍙兘绛夊緟銆?/p>

銆€銆€鍦?Java 涓紝鍙互浣跨敤 synchronized 鍏抽敭瀛楁潵鏍囪涓€涓柟娉曟垨鑰呬唬鐮佸潡锛屽綋鏌愪釜绾跨▼璋冪敤璇ュ璞$殑synchronized鏂规硶鎴栬€呰闂畇ynchronized浠g爜鍧楁椂锛岃繖涓嚎绋嬩究鑾峰緱浜嗚瀵硅薄鐨勯攣锛屽叾浠栫嚎绋嬫殏鏃舵棤娉曡闂繖涓柟娉曪紝鍙湁绛夊緟杩欎釜鏂规硶鎵ц瀹屾瘯鎴栬€呬唬鐮佸潡鎵ц瀹屾瘯锛岃繖涓嚎绋嬫墠浼氶噴鏀捐瀵硅薄鐨勯攣锛屽叾浠栫嚎绋嬫墠鑳芥墽琛岃繖涓柟娉曟垨鑰呬唬鐮佸潡銆?/p>

銆€銆€涓嬮潰杩欐浠g爜涓袱涓嚎绋嬪垎鍒皟鐢╥nsertData瀵硅薄鎻掑叆鏁版嵁锛?br />1) synchronized鏂规硶

public class Test 

    public static void main(String[] args)  
        final InsertData insertData = new InsertData();
        // 鍚姩绾跨▼ 1  
        new Thread() 
            public void run() 
                insertData.insert(Thread.currentThread());
            ;
        .start();

        // 鍚姩绾跨▼ 2
        new Thread() 
            public void run() 
                insertData.insert(Thread.currentThread());
            ;
        .start();
      


class InsertData 

    // 鍏变韩銆佸彲鍙樿祫婧?/span>
    private ArrayList<Integer> arrayList = new ArrayList<Integer>();

    //瀵瑰叡浜彲鍙樿祫婧愮殑璁块棶
    public void insert(Thread thread)
        for(int i=0;i<5;i++)
            System.out.println(thread.getName()+"鍦ㄦ彃鍏ユ暟鎹?+i);
            arrayList.add(i);
        
    
/* Output: 
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
 */

鏍规嵁杩愯缁撴灉灏卞彲浠ョ湅鍑猴紝杩欎袱涓嚎绋嬪湪鍚屾椂鎵цinsert()鏂规硶銆傝€屽鏋滃湪insert()鏂规硶鍓嶉潰鍔犱笂鍏抽敭瀛梥ynchronized 鐨勮瘽锛岃繍琛岀粨鏋滀负锛?/p>

class InsertData 
    private ArrayList<Integer> arrayList = new ArrayList<Integer>();

    public synchronized void insert(Thread thread)
        for(int i=0;i<5;i++)
            System.out.println(thread.getName()+"鍦ㄦ彃鍏ユ暟鎹?+i);
            arrayList.add(i);
        
    
/* Output: 
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-0鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
        Thread-1鍦ㄦ彃鍏ユ暟鎹?
 */

銆€浠庝互涓婅緭鍑虹粨鏋滃彲浠ョ湅鍑猴紝Thread-1 鎻掑叆鏁版嵁鏄瓑 Thread-0 鎻掑叆瀹屾暟鎹箣鍚庢墠杩涜鐨勩€傝鏄?Thread-0 鍜?Thread-1 鏄『搴忔墽琛?insert() 鏂规硶鐨勩€傝繖灏辨槸 synchronized 鍏抽敭瀛楀鏂规硶鐨勪綔鐢ㄣ€?/p>

銆€銆€涓嶈繃闇€瑕佹敞鎰忎互涓嬩笁鐐癸細

銆€銆€1锛夊綋涓€涓嚎绋嬫鍦ㄨ闂竴涓璞$殑 synchronized 鏂规硶锛岄偅涔堝叾浠栫嚎绋嬩笉鑳借闂瀵硅薄鐨勫叾浠?synchronized 鏂规硶銆傝繖涓師鍥犲緢绠€鍗曪紝鍥犱负涓€涓璞″彧鏈変竴鎶婇攣锛屽綋涓€涓嚎绋嬭幏鍙栦簡璇ュ璞$殑閿佷箣鍚庯紝鍏朵粬绾跨▼鏃犳硶鑾峰彇璇ュ璞$殑閿侊紝鎵€浠ユ棤娉曡闂瀵硅薄鐨勫叾浠杝ynchronized鏂规硶銆?/p>

銆€銆€2锛夊綋涓€涓嚎绋嬫鍦ㄨ闂竴涓璞$殑 synchronized 鏂规硶锛岄偅涔堝叾浠栫嚎绋嬭兘璁块棶璇ュ璞$殑闈?synchronized 鏂规硶銆傝繖涓師鍥犲緢绠€鍗曪紝璁块棶闈?synchronized 鏂规硶涓嶉渶瑕佽幏寰楄瀵硅薄鐨勯攣锛屽亣濡備竴涓柟娉曟病鐢?synchronized 鍏抽敭瀛椾慨楗帮紝璇存槑瀹冧笉浼氫娇鐢ㄥ埌涓寸晫璧勬簮锛岄偅涔堝叾浠栫嚎绋嬫槸鍙互璁块棶杩欎釜鏂规硶鐨勶紝

銆€銆€3锛夊鏋滀竴涓嚎绋?A 闇€瑕佽闂璞?object1 鐨?synchronized 鏂规硶 fun1锛屽彟澶栦竴涓嚎绋?B 闇€瑕佽闂璞?object2 鐨?synchronized 鏂规硶 fun1锛屽嵆浣?object1 鍜?object2 鏄悓涓€绫诲瀷锛夛紝涔熶笉浼氫骇鐢熺嚎绋嬪畨鍏ㄩ棶棰橈紝鍥犱负浠栦滑璁块棶鐨勬槸涓嶅悓鐨勫璞★紝鎵€浠ヤ笉瀛樺湪浜掓枼闂銆?/p>

2) synchronized 鍚屾鍧?/strong>

synchronized 浠g爜鍧楃被浼间簬浠ヤ笅杩欑褰㈠紡锛?/p>

synchronized (lock)
    //璁块棶鍏变韩鍙彉璧勬簮
    ...

褰撳湪鏌愪釜绾跨▼涓墽琛岃繖娈典唬鐮佸潡锛岃绾跨▼浼氳幏鍙栧璞ock鐨勯攣锛屼粠鑰屼娇寰楀叾浠栫嚎绋嬫棤娉曞悓鏃惰闂浠g爜鍧椼€傚叾涓紝lock 鍙互鏄?this锛屼唬琛ㄨ幏鍙栧綋鍓嶅璞$殑閿侊紝涔熷彲浠ユ槸绫讳腑鐨勪竴涓睘鎬э紝浠h〃鑾峰彇璇ュ睘鎬х殑閿併€傜壒鍒湴锛?瀹炰緥鍚屾鏂规硶 涓?synchronized(this)鍚屾鍧?鏄簰鏂ョ殑锛屽洜涓哄畠浠攣鐨勬槸鍚屼竴涓璞°€備絾涓?synchronized(闈瀟his)鍚屾鍧?鏄紓姝ョ殑锛屽洜涓哄畠浠攣鐨勬槸涓嶅悓瀵硅薄銆?br />姣斿涓婇潰鐨刬nsert()鏂规硶鍙互鏀规垚浠ヤ笅涓ょ褰㈠紡锛?/p>

// this 鐩戣鍣?/span>
class InsertData 
    private ArrayList<Integer> arrayList = new ArrayList<Integer>();

    public void insert(Thread thread)
        synchronized (this) 
            for(int i=0;i<100;i++)
                System.out.println(thread.getName()+"鍦ㄦ彃鍏ユ暟鎹?+i);
                arrayList.add(i);
            
        
    


// 瀵硅薄鐩戣鍣?/span>
class InsertData 
    private ArrayList<Integer> arrayList = new ArrayList<Integer>();
    private Object object = new Object();

    public void insert(Thread thread)
        synchronized (object) 
            for(int i=0;i<100;i++)
                System.out.println(thread.getName()+"鍦ㄦ彃鍏ユ暟鎹?+i);
                arrayList.add(i);
            
        
    

浠庝笂闈唬鐮佸彲浠ョ湅鍑猴紝synchronized浠g爜鍧?姣?synchronized鏂规硶 鐨勭矑搴︽洿缁嗕竴浜涳紝浣跨敤璧锋潵涔熺伒娲诲緱澶氥€傚洜涓轰篃璁镐竴涓柟娉曚腑鍙湁涓€閮ㄥ垎浠g爜鍙渶瑕佸悓姝ワ紝濡傛灉姝ゆ椂瀵规暣涓柟娉曠敤synchronized杩涜鍚屾锛屼細褰卞搷绋嬪簭鎵ц鏁堢巼銆傝€屼娇鐢╯ynchronized浠g爜鍧楀氨鍙互閬垮厤杩欎釜闂锛宻ynchronized浠g爜鍧楀彲浠ュ疄鐜板彧瀵归渶瑕佸悓姝ョ殑鍦版柟杩涜鍚屾銆?/p>

3) class 瀵硅薄閿?/strong>

銆€銆€鐗瑰埆鍦帮紝姣忎釜绫讳篃浼氭湁涓€涓攣锛岄潤鎬佺殑 synchronized鏂规硶 灏辨槸浠lass瀵硅薄浣滀负閿併€傚彟澶栵紝瀹冨彲浠ョ敤鏉ユ帶鍒跺 static 鏁版嵁鎴愬憳 锛坰tatic 鏁版嵁鎴愬憳涓嶄笓灞炰簬浠讳綍涓€涓璞★紝鏄被鎴愬憳锛?鐨勫苟鍙戣闂€傚苟涓旓紝濡傛灉涓€涓嚎绋嬫墽琛屼竴涓璞$殑闈瀞tatic synchronized 鏂规硶锛屽彟澶栦竴涓嚎绋嬮渶瑕佹墽琛岃繖涓璞℃墍灞炵被鐨?static synchronized 鏂规硶锛屼篃涓嶄細鍙戠敓浜掓枼鐜拌薄銆傚洜涓鸿闂?static synchronized 鏂规硶鍗犵敤鐨勬槸绫婚攣锛岃€岃闂潪 static synchronized 鏂规硶鍗犵敤鐨勬槸瀵硅薄閿侊紝鎵€浠ヤ笉瀛樺湪浜掓枼鐜拌薄銆備緥濡傦紝

public class Test 

    public static void main(String[] args)  
        final InsertData insertData = new InsertData();
        new Thread()
            @Override
            public void run() 
                insertData.insert();
            
        .start(); 
        new Thread()
            @Override
            public void run() 
                insertData.insert1();
            
        .start();
      


class InsertData  

    // 闈?static synchronized 鏂规硶
    public synchronized void insert()
        System.out.println("鎵цinsert");
        try 
            Thread.sleep(5000);
         catch (InterruptedException e) 
            e.printStackTrace();
        
        System.out.println("鎵цinsert瀹屾瘯");
    

    // static synchronized 鏂规硶
    public synchronized static void insert1() 
        System.out.println("鎵цinsert1");
        System.out.println("鎵цinsert1瀹屾瘯");
    
/* Output: 
        鎵цinsert
        鎵цinsert1
        鎵цinsert1瀹屾瘯
        鎵цinsert瀹屾瘯
 */

鏍规嵁鎵ц缁撴灉锛屾垜浠彲浠ョ湅鍒扮涓€涓嚎绋嬮噷闈㈡墽琛岀殑鏄痠nsert鏂规硶锛屼笉浼氬鑷寸浜屼釜绾跨▼鎵цinsert1鏂规硶鍙戠敓闃诲鐜拌薄銆備笅闈紝鎴戜滑鐪嬩竴涓?synchronized 鍏抽敭瀛楀埌搴曞仛浜嗕粈涔堜簨鎯咃紝鎴戜滑鏉ュ弽缂栬瘧瀹冪殑瀛楄妭鐮佺湅涓€涓嬶紝涓嬮潰杩欐浠g爜鍙嶇紪璇戝悗鐨勫瓧鑺傜爜涓猴細

public class InsertData 
    private Object object = new Object();

    public void insert(Thread thread)
        synchronized (object) 
    

    public synchronized void insert1(Thread thread)

    public void insert2(Thread thread)

鎶€鏈浘鐗? src=

 

 

 

浠庡弽缂栬瘧鑾峰緱鐨勫瓧鑺傜爜鍙互鐪嬪嚭锛宻ynchronized 浠g爜鍧楀疄闄呬笂澶氫簡 monitorenter 鍜?monitorexit 涓ゆ潯鎸囦护銆?monitorenter鎸囦护鎵ц鏃朵細璁╁璞$殑閿佽鏁板姞1锛岃€宮onitorexit鎸囦护鎵ц鏃朵細璁╁璞$殑閿佽鏁板噺1锛屽叾瀹炶繖涓笌鎿嶄綔绯荤粺閲岄潰鐨凱V鎿嶄綔寰堝儚锛屾搷浣滅郴缁熼噷闈㈢殑PV鎿嶄綔灏辨槸鐢ㄦ潵鎺у埗澶氫釜杩涚▼瀵逛复鐣岃祫婧愮殑璁块棶銆傚浜巗ynchronized鏂规硶锛屾墽琛屼腑鐨勭嚎绋嬭瘑鍒鏂规硶鐨?method_info 缁撴瀯鏄惁鏈?ACC_SYNCHRONIZED 鏍囪璁剧疆锛岀劧鍚庡畠鑷姩鑾峰彇瀵硅薄鐨勯攣锛岃皟鐢ㄦ柟娉曪紝鏈€鍚庨噴鏀鹃攣銆傚鏋滄湁寮傚父鍙戠敓锛岀嚎绋嬭嚜鍔ㄩ噴鏀鹃攣銆?/p>

銆€銆€鏈変竴鐐硅娉ㄦ剰锛氬浜?synchronized鏂规硶 鎴栬€?synchronized浠g爜鍧楋紝褰撳嚭鐜板紓甯告椂锛孞VM浼氳嚜鍔ㄩ噴鏀惧綋鍓嶇嚎绋嬪崰鐢ㄧ殑閿侊紝鍥犳涓嶄細鐢变簬寮傚父瀵艰嚧鍑虹幇姝婚攣鐜拌薄銆傘€€銆€

鍙噸鍏ラ攣鏈€澶х殑浣滅敤鏄伩鍏嶆閿併€?/span>渚嬪锛?/p>
public class Test implements Runnable 

    // 鍙噸鍏ラ攣娴嬭瘯
    public synchronized void get() 
        System.out.println(Thread.currentThread().getName());
        set();
    

    public synchronized void set() 
        System.out.println(Thread.currentThread().getName());
    

    @Override
    public void run() 
        get();
    

    public static void main(String[] args) 
        Test test = new Test();
        new Thread(test,"Thread-0").start();
        new Thread(test,"Thread-1").start();
        new Thread(test,"Thread-2").start();
    
/* Output: 
        Thread-1
        Thread-1
        Thread-2
        Thread-2
        Thread-0
        Thread-0
 */

浜? 娉ㄦ剰浜嬮」

1). 鍐呯疆閿佷笌瀛楃涓插父閲?/strong>

銆€銆€鐢变簬瀛楃涓插父閲忔睜鐨勫師鍥狅紝鍦ㄥぇ澶氭暟鎯呭喌涓嬶紝鍚屾synchronized浠g爜鍧?閮戒笉浣跨敤 String 浣滀负閿佸璞★紝鑰屾敼鐢ㄥ叾浠栵紝姣斿 new Object() 瀹炰緥鍖栦竴涓?Object 瀵硅薄锛屽洜涓哄畠骞朵笉浼氳鏀惧叆缂撳瓨涓€傜湅涓嬮潰鐨勪緥瀛愶細

//璧勬簮绫?/span>
class Service 
    public void print(String stringParam) 
        try 
            synchronized (stringParam) 
                while (true) 
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                
            
         catch (InterruptedException e) 
            e.printStackTrace();
        
    


//绾跨▼A
class ThreadA extends Thread 
    private Service service;

    public ThreadA(Service service) 
        super();
        this.service = service;
    

    @Override
    public void run() 
        service.print("AA");
    


//绾跨▼B
class ThreadB extends Thread 
    private Service service;

    public ThreadB(Service service) 
        super();
        this.service = service;
    

    @Override
    public void run() 
        service.print("AA");
    


//娴嬭瘯
public class Run 
    public static void main(String[] args) 

        //涓寸晫璧勬簮
        Service service = new Service();

        //鍒涘缓骞跺惎鍔ㄧ嚎绋婣
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        //鍒涘缓骞跺惎鍔ㄧ嚎绋婤
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

    
/* Output (姝婚攣): 
        A
        A
        A
        A
        ...
 */

鍑虹幇涓婅堪缁撴灉灏辨槸鍥犱负 String 绫诲瀷鐨勫弬鏁伴兘鏄?“AA”锛屼袱涓嚎绋嬫寔鏈夌浉鍚岀殑閿侊紝鎵€浠?绾跨▼B 濮嬬粓寰椾笉鍒版墽琛岋紝閫犳垚姝婚攣銆傝繘涓€姝ュ湴锛屾墍璋撴閿佹槸鎸囷細 涓嶅悓鐨勭嚎绋嬮兘鍦ㄧ瓑寰呮牴鏈笉鍙兘琚噴鏀剧殑閿侊紝浠庤€屽鑷存墍鏈夌殑浠诲姟閮芥棤娉曠户缁畬鎴愩€?/em>

b). 閿佺殑鏄璞¤€岄潪寮曠敤

銆€銆€鍦ㄥ皢浠讳綍鏁版嵁绫诲瀷浣滀负鍚屾閿佹椂锛岄渶瑕佹敞鎰忕殑鏄紝鏄惁鏈夊涓嚎绋嬪皢鍚屾椂鍘荤珵浜夎閿佸璞★細 
銆€銆€1).鑻ュ畠浠皢鍚屾椂绔炰簤鍚屼竴鎶婇攣锛屽垯杩欎簺绾跨▼涔嬮棿灏辨槸鍚屾鐨勶紱 
銆€銆€2).鍚﹀垯锛岃繖浜涚嚎绋嬩箣闂村氨鏄紓姝ョ殑銆?/p>

鐪嬩笅闈㈢殑渚嬪瓙:

//璧勬簮绫?/span>
class MyService 
    private String lock = "123";

    public void testMethod() 
        try 
            synchronized (lock) 
                System.out.println(Thread.currentThread().getName() + " begin "
                        + System.currentTimeMillis());
                lock = "456";
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "   end "
                        + System.currentTimeMillis());
            
         catch (InterruptedException e) 
            e.printStackTrace();
        
    


//绾跨▼B
class ThreadB extends Thread 

    private MyService service;

    public ThreadB(MyService service) 
        super();
        this.service = service;
    

    @Override
    public void run() 
        service.testMethod();
    


//绾跨▼A
class ThreadA extends Thread 

    private MyService service;

    public ThreadA(MyService service) 
        super();
        this.service = service;
    

    @Override
    public void run() 
        service.testMethod();
    


//娴嬭瘯
public class Run1 
    public static void main(String[] args) throws InterruptedException 

        //涓寸晫璧勬簮
        MyService service = new MyService();

        //绾跨▼A
        ThreadA a = new ThreadA(service);
        a.setName("A");

        //绾跨▼B
        ThreadB b = new ThreadB(service);
        b.setName("B");

        a.start();
        Thread.sleep(50);// 瀛樺湪50姣
        b.start();
    
/* Output(寰幆): 
       A begin 1484319778766
       B begin 1484319778815
       A   end 1484319780766
       B   end 1484319780815
 */

鐢变笂杩扮粨鏋滃彲鐭ワ紝绾跨▼ A銆丅 鏄紓姝ョ殑銆傚洜涓?0姣杩囧悗锛?绾跨▼B 鍙栧緱鐨勯攣瀵硅薄鏄?“456”锛岃€?绾跨▼A 渚濈劧鎸佹湁鐨勯攣瀵硅薄鏄?“123”銆傛墍浠ワ紝杩欎袱涓嚎绋嬫槸寮傛鐨勩€傝嫢灏嗕笂杩拌鍙?“Thread.sleep(50);” 娉ㄩ噴锛屽垯鏈夛細

//娴嬭瘯
public class Run1 
    public static void main(String[] args) throws InterruptedException 

        //涓寸晫璧勬簮
        MyService service = new MyService();

        //绾跨▼A
        ThreadA a = new ThreadA(service);
        a.setName("A");

        //绾跨▼B
        ThreadB b = new ThreadB(service);
        b.setName("B");

        a.start();
        // Thread.sleep(50);// 瀛樺湪50姣
        b.start();
    
/* Output(寰幆): 
       B begin 1484319952017
       B   end 1484319954018
       A begin 1484319954018
       A   end 1484319956019
 */

鐢变笂杩扮粨鏋滃彲鐭ワ紝绾跨▼ A銆丅 鏄悓姝ョ殑銆傚洜涓虹嚎绋?A銆丅 绔炰簤鐨勬槸鍚屼竴涓攣“123”锛岃櫧鐒跺厛鑾峰緱杩愯鐨勭嚎绋嬪皢 lock 鎸囧悜浜?瀵硅薄“456”锛屼絾缁撴灉杩樻槸鍚屾鐨勩€傚洜涓虹嚎绋?A 鍜?B 鍏卞悓浜夋姠鐨勯攣瀵硅薄鏄?ldquo;123”锛屼篃灏辨槸璇达紝閿佺殑鏄璞¤€岄潪寮曠敤銆?/span>

灏忕粨:

銆€鐢ㄤ竴鍙ヨ瘽鏉ヨ锛宻ynchronized 鍐呯疆閿?鏄竴绉?瀵硅薄閿?(閿佺殑鏄璞¤€岄潪寮曠敤)锛?浣滅敤绮掑害鏄璞?锛屽彲浠ョ敤鏉ュ疄鐜板 涓寸晫璧勬簮鐨勫悓姝ヤ簰鏂ヨ闂?锛屾槸 鍙噸鍏?鐨勩€傜壒鍒湴锛屽浜?涓寸晫璧勬簮 鏈夛細

  • 鑻ヨ璧勬簮鏄潤鎬佺殑锛屽嵆琚?static 鍏抽敭瀛椾慨楗帮紝閭d箞璁块棶瀹冪殑鏂规硶蹇呴』鏄悓姝ヤ笖鏄潤鎬佺殑锛宻ynchronized 鍧楀繀椤绘槸 class閿侊紱
  • 鑻ヨ璧勬簮鏄潪闈欐€佺殑锛屽嵆娌℃湁琚?static 鍏抽敭瀛椾慨楗帮紝閭d箞璁块棶瀹冪殑鏂规硶蹇呴』鏄悓姝ョ殑锛宻ynchronized 鍧楁槸瀹炰緥瀵硅薄閿侊紱

瀹炶川涓婏紝鍏抽敭瀛梥ynchronized 涓昏鍖呭惈涓や釜鐗瑰緛锛?/p>

  • 浜掓枼鎬э細淇濊瘉鍦ㄥ悓涓€鏃跺埢锛屽彧鏈変竴涓嚎绋嬪彲浠ユ墽琛屾煇涓€涓柟娉曟垨鏌愪竴涓唬鐮佸潡锛?/li>
  • 鍙鎬э細淇濊瘉绾跨▼宸ヤ綔鍐呭瓨涓殑鍙橀噺涓庡叕鍏卞唴瀛樹腑鐨勫彉閲忓悓姝ワ紝浣垮绾跨▼璇诲彇鍏变韩鍙橀噺鏃跺彲浠ヨ幏寰楁渶鏂板€肩殑浣跨敤銆?/li>

 

以上是关于Java 骞跺彂锛氬唴缃攣 Synchronized的主要内容,如果未能解决你的问题,请参考以下文章

骞跺彂鐩稿叧闂浠ュ強java鍩虹鐭ヨ瘑

Java骞跺彂缂栫▼鐨勮壓鏈紙浜旓級Java鍐呭瓨妯″瀷

浣跨敤Promise骞跺彂闄愬埗

銆愬師鍒涖€慗ava骞跺彂缂栫▼绯诲垪30 | ThreadLocal

Redis瀹炴垬锛氬井淇℃姠绾㈠寘銆丣meter鍘嬫祴锛堥檮婧愮爜锛?/h1>

姣忎竴涓▼搴忓憳閮藉簲璇ョ煡閬撶殑楂樺苟鍙戝鐞嗘妧宸с€佸垱涓氬叕鍙稿浣曡В鍐抽珮骞跺彂闂銆佷簰鑱旂綉楂樺苟鍙戦棶棰樿В鍐虫€濊矾銆乧aoz澶х澶氬勾缁忛獙鎬荤粨鍒嗕韩

(c)2006-2024 SYSTEM All Rights Reserved IT常识