java 中同步实例方法通过在方法签名添加 synchronized 关键字来实现,此时 jvm 会自动获取当前对象实例(即 this)的监视器锁。这意味着同一时刻只有一个线程能执行该对象的任意同步实例方法,从而保证线程安全。调用该方法前无需显式获取锁,但需注意它锁定的是实例而非类。

如何验证 synchronized 实例方法的互斥性
要验证同步实例方法的互斥效果,可以创建两个线程同时访问同一个对象的不同同步方法。由于它们共享同一个锁对象(this),后进入的线程必须等待持有锁的线程执行完毕。这种机制确保了临界区代码的原子性,防止数据竞争。

import java.util.concurrent.CountDownLatch;
public class SynchronizedDemo {
public synchronized void methodA() {
try {
System.out.println("Method A started");
Thread.sleep(1000);
System.out.println("Method A ended");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void methodB() {
System.out.println("Method B executed");
}
public static void main(String[] args) throws InterruptedException {
SynchronizedDemo demo = new SynchronizedDemo();
CountDownLatch latch = new CountDownLatch(2);
new Thread(() -> {
demo.methodA();
latch.countDown();
}).start();
new Thread(() -> {
demo.methodB();
latch.countDown();
}).start();
latch.await();
System.out.println("All threads finished");
}
}
不同实例间的 synchronized 方法是否互斥
当多个线程分别访问同一个类的不同实例时,synchronized 实例方法不会互相阻塞。因为每个实例都有自己独立的监视器锁,线程 A 锁定实例 1 并不影响线程 B 锁定实例 2。这种设计允许在多线程环境下对不同的业务对象进行并发处理,提高系统的吞吐量。
立即学习“Java免费学习笔记(深入)”;

import java.util.concurrent.CountDownLatch;
public class MultiInstanceDemo {
public synchronized void process() {
System.out.println(Thread.currentThread().getName() + " processing instance: " + this.hashCode());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
MultiInstanceDemo instance1 = new MultiInstanceDemo();
MultiInstanceDemo instance2 = new MultiInstanceDemo();
CountDownLatch latch = new CountDownLatch(2);
new Thread(() -> {
instance1.process();
latch.countDown();
}, "Thread-1").start();
new Thread(() -> {
instance2.process();
latch.countDown();
}, "Thread-2").start();
latch.await();
System.out.println("Concurrent execution completed");
}
}
synchronized 实例方法在非静态上下文中的行为
在非静态上下文中,synchronized 关键字隐式地绑定到当前对象实例。如果在一个普通方法中使用 synchronized(this) 块,其效果与方法级声明完全一致。这种灵活性允许开发者更精细地控制锁的范围,例如只对方法中的某段代码加锁,而不是整个方法体,从而减少锁持有时间。


















