You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用同一类不同实例调用synchronized方法的执行逻辑及顺序控制

synchronized修饰实例方法多实例调用逻辑及顺序执行方案

原示例代码

public class A1 {

    public synchronized void m1(){

        try{
            
            Thread.sleep(5000);

        }catch(Exception e){

        }
    }


    public static void main(String[] args) {
        A1 o1 = new A1();
        A1 o2 = new A1();
        o1.m1();
        o2.m1();
    }
}

现有场景执行逻辑

synchronized修饰实例方法时,绑定的锁对象是当前方法所属的实例本身(即this),因此不同实例的同步方法持有的锁完全独立:

  • 你给出的示例是在main主线程中顺序调用两个实例的m1方法,本身就会按代码顺序执行:先执行完o1的m1方法(阻塞5秒),再执行o2的m1方法(再阻塞5秒),总耗时约10秒。
  • 如果是启动两个独立线程分别调用o1.m1()和o2.m1(),两个线程不存在锁竞争,会并行执行,总耗时约5秒,执行顺序由CPU调度决定,无法保证固定顺序。

强制两次调用按顺序执行的方案

如果是多线程调用场景下需要保证两个实例的m1方法按指定顺序执行,可参考以下方案:

方案1:替换为类级别锁

修改方法的锁粒度为类级别,所有实例调用该方法都需要竞争同一个类锁,天然保证串行执行:

public class A1 {
    // 方式1:改为静态同步方法,锁对象为A1.class
    public static synchronized void m1(){
        try{
            Thread.sleep(5000);
        }catch(Exception e){
        }
    }

    // 方式2:不修改方法静态属性,方法内部加类锁
    public void m1(){
        synchronized(A1.class){
            try{
                Thread.sleep(5000);
            }catch(Exception e){
            }
        }
    }
}

方案2:调用侧使用共享锁

不修改原有A1类的代码,在调用层定义全局共享的锁对象,两个调用都需要先获取该锁才能执行:

public static void main(String[] args) {
    A1 o1 = new A1();
    A1 o2 = new A1();
    // 共享锁对象
    Object sharedLock = new Object();

    new Thread(() -> {
        synchronized (sharedLock) {
            o1.m1();
        }
    }).start();

    new Thread(() -> {
        synchronized (sharedLock) {
            o2.m1();
        }
    }).start();
}

方案3:使用线程协调工具

用CountDownLatch等JUC工具实现前一个执行完成后再触发后一个调用,顺序可控:

import java.util.concurrent.CountDownLatch;

public static void main(String[] args) throws InterruptedException {
    A1 o1 = new A1();
    A1 o2 = new A1();
    CountDownLatch latch = new CountDownLatch(1);

    // 先执行o1的调用
    new Thread(() -> {
        o1.m1();
        latch.countDown();
    }).start();

    // 等待o1执行完成后再启动o2的调用
    latch.await();
    new Thread(() -> o2.m1()).start();
}

内容的提问来源于stack exchange,提问作者Saurav Shrivastav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:18:03