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

Java多线程疑问:为何Thread2可在Thread1未退出时进入同步方法?

问题:同步方法为何未按预期实现线程互斥?

示例代码

public class MyThread extends Thread {
    public synchronized void logic() {
        System.out.println("Thread started");
        System.out.println(Thread.currentThread().getName());

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread ended");
    }
    
    public void run() {
        System.out.println("inside run method");
        logic();
    }

    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        MyThread thread3 = new MyThread();

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

运行输出

inside run method
inside run method
Thread started
inside run method
Thread-1
Thread started
Thread-0
Thread started
Thread-2
<<<After few seconds>>>
Thread ended
Thread ended
Thread ended

疑问点

调用thread.start()后,所有线程都能进入run方法;logic方法是synchronized同步方法,按理解当一个线程进入同步方法时,其他线程需等待该线程执行完毕才能进入。但从输出可见,Thread-1进入logic方法并打印“Thread started”且未执行完毕时,Thread-0、Thread-2也能进入logic方法并打印“Thread started”,为何会出现这种情况?预期应该是只有当没有线程处于logic方法中时,其他线程才能进入该方法。

原因解析

核心问题出在同步锁的对象范围上:

  • 当synchronized修饰实例方法时,它的锁是当前对象实例(this)。
  • 代码里创建了三个独立的MyThread对象:thread1、thread2、thread3,每个线程对应的锁是各自的对象实例,这三个锁完全互不关联。
  • 所以每个线程进入logic方法时,获取的是自己对象的锁,不会和其他线程的锁产生竞争,自然不需要等待其他线程执行完毕,多个线程可以同时进入各自的logic方法。

解决方法

如果要让所有线程共用同一把锁,实现互斥执行logic方法,有两种常见方案:

  • 将logic方法改为静态同步方法:静态方法的锁是当前类的Class对象(MyThread.class),所有线程共用这一把锁。
    public static synchronized void logic() {
        // 方法内容不变
    }
    
  • 在实例方法中,使用类对象作为锁:
    public void logic() {
        synchronized(MyThread.class) {
            // 原方法内容放在同步代码块内
            System.out.println("Thread started");
            System.out.println(Thread.currentThread().getName());
    
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("Thread ended");
        }
    }
    

内容的提问来源于stack exchange,提问作者Asif Sk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:20:26