首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 線程同步:同步代碼塊優化性能

     編輯:Java 相關知識

同步代碼塊動機

同步方法鎖住整個方法,粒度較粗。同步代碼塊(synchronized(obj) { ... })允許僅鎖住訪問共享資源的關鍵區段,減少鎖持有時間,提升並發性能。

代碼示例:同步塊替換同步方法

/** 
 * Java線程:線程的同步-同步代碼塊
 * @author leizhimin 
 */
public class Test {
    public static void main(String[] args) {
        User u = new User("張三", 100);
        MyThread t1 = new MyThread("線程A", u, 20);
        MyThread t2 = new MyThread("線程B", u, -60);
        MyThread t3 = new MyThread("線程C", u, -80);
        MyThread t4 = new MyThread("線程D", u, -30);
        MyThread t5 = new MyThread("線程E", u, 32);
        MyThread t6 = new MyThread("線程F", u, 21);
        t1.start(); t2.start(); t3.start(); t4.start(); t5.start(); t6.start();
    }
}

class MyThread extends Thread {
    private User u; private int y;
    MyThread(String name, User u, int y) { super(name); this.u = u; this.y = y; }
    public void run() { u.oper(y); }
}

class User {
    private String code; private int cash;
    User(String code, int cash) { this.code = code; this.cash = cash; }
    public String getCode() { return code; }
    public void setCode(String code) { this.code = code; }
    
    /** 業務方法:使用同步代碼塊 */
    public void oper(int x) {
        try {
            Thread.sleep(10L);
            synchronized (this) {  // 僅鎖住關鍵修改區
                this.cash += x;
                System.out.println(Thread.currentThread().getName() + "運行結束,增加\"" + x + "\",當前用戶賬戶余額為:" + cash);
            }
            Thread.sleep(10L);
        } catch (InterruptedException e) { e.printStackTrace(); }
    }
    @Override public String toString() { return "User{code='" + code + "', cash=" + cash + '}'; }
}

運行結果(正確)

線程E運行結束,增加"32",當前用戶賬戶余額為:132
線程B運行結束,增加"-60",當前用戶賬戶余額為:72
線程D運行結束,增加"-30",當前用戶賬戶余額為:42
線程F運行結束,增加"21",當前用戶賬戶余額為:63
線程C運行結束,增加"-80",當前用戶賬戶余額為:-17
線程A運行結束,增加"20",當前用戶賬戶余額為:3
Process finished with exit code 0

最終餘額 3 正確,說明同步塊同樣保證了線程安全。

關鍵注意事項

  • 避免在同步塊中調用 sleep/yield:持有鎖時睡眠會阻塞其他線程,嚴重降低吞吐量
  • 鎖對象選擇:用 this、私有 final 對象或專用鎖對象,避免用字符串常量或可變對象
  • 最小化同步範圍:只同步必要的共享狀態操作,計算、I/O 等移出同步塊
  • 死鎖風險:多鎖時保持固定獲取順序

同步方法 vs 同步塊對比

維度同步方法同步代碼塊
語法簡潔性高稍低
鎖粒度整個方法可精確控制
性能潛力較低較高
靈活性固定鎖 this/Class可指定任意鎖對象

出處:https://lavasoft.blog.51cto.com/62575/221922

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved