Java中能否在同步方法内定义同步代码块?请举例说明
Java同步方法内部能否定义同步代码块?
嘿,当然可以!Java不仅允许在synchronized方法内部定义synchronized代码块,这种写法在实际开发中还挺常见的——主要是为了更精细地控制锁的范围,或者利用内置锁的可重入特性来实现嵌套同步。
先给你理清楚核心逻辑:Java的内置锁(也就是对象锁)是可重入的,意思是如果一个线程已经持有某个对象的锁,那么它再次请求这个锁的时候不会被自己阻塞。这就为嵌套同步提供了基础。
下面给你两个常见的示例场景:
场景1:同步方法与内部代码块锁同一个对象(可重入演示)
这种情况里,同步方法默认锁的是当前对象(this),内部的同步代码块也显式锁this,线程可以顺利进入,不会发生死锁。
public class ReentrantLockDemo { // 同步方法,默认锁当前对象this public synchronized void outerSyncMethod() { System.out.println("进入同步方法,当前线程:" + Thread.currentThread().getName()); // 内部定义同步代码块,锁同一个对象this synchronized (this) { System.out.println("进入内部同步代码块,当前线程:" + Thread.currentThread().getName()); // 这里可以执行需要更细粒度同步的逻辑 doSomething(); } System.out.println("退出同步方法,当前线程:" + Thread.currentThread().getName()); } private void doSomething() { // 模拟业务逻辑 try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public static void main(String[] args) { ReentrantLockDemo demo = new ReentrantLockDemo(); // 启动两个线程测试 new Thread(demo::outerSyncMethod, "线程A").start(); new Thread(demo::outerSyncMethod, "线程B").start(); } }
运行这段代码你会看到,线程A先进入同步方法,然后顺利进入内部代码块,执行完后释放锁,线程B才会开始执行——完全符合预期,没有阻塞问题。
场景2:同步方法与内部代码块锁不同对象(细粒度锁控制)
有时候我们不想让整个方法都被锁死,只想对方法内的某一段代码加锁,或者需要锁另一个独立的对象来避免不必要的锁竞争,这时候就可以在同步方法内部用不同的锁对象。
public class DifferentLockDemo { // 定义一个独立的锁对象,用于内部代码块 private final Object innerLock = new Object(); // 同步方法,锁当前对象this public synchronized void outerSyncMethod() { System.out.println("进入同步方法,当前线程:" + Thread.currentThread().getName()); // 这里是不需要同步的逻辑,比如一些只读操作 System.out.println("执行非同步逻辑,当前线程:" + Thread.currentThread().getName()); // 内部同步代码块,锁独立的innerLock对象 synchronized (innerLock) { System.out.println("进入内部同步代码块(锁innerLock),当前线程:" + Thread.currentThread().getName()); // 这里执行需要单独同步的逻辑,比如修改特定资源 updateCriticalResource(); } System.out.println("退出同步方法,当前线程:" + Thread.currentThread().getName()); } private void updateCriticalResource() { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } public static void main(String[] args) { DifferentLockDemo demo = new DifferentLockDemo(); new Thread(demo::outerSyncMethod, "线程X").start(); new Thread(demo::outerSyncMethod, "线程Y").start(); } }
这个例子里,同步方法锁this,内部代码块锁innerLock,两者是独立的锁。这样设计的好处是,如果其他地方有只需要锁innerLock的逻辑,不会被this锁的竞争影响,提升了并发效率。
总结一下:
- 允许在
synchronized方法内部定义synchronized代码块,得益于Java内置锁的可重入性。 - 可以选择锁同一个对象(利用可重入),或者不同对象(实现细粒度锁),根据业务需求灵活调整。
内容的提问来源于stack exchange,提问作者Karthik Reddy V V
相关产品推荐
相关产品推荐

