synchronized的特性
synchronized是Java中用于实现线程同步的关键字,它的主要特性包括:
-
原子性(Atomicity):synchronized 确保一个代码块在同一时刻只能被一个线程执行,从而避免了多个线程同时访问同一个资源导致的数据不一致问题。
-
可见性(Visibility):当一个线程获取了对象的锁,它会清空工作内存中的共享变量的值,从而使用主内存中的最新值,保证了共享变量的可见性。
-
互斥性(Mutual Exclusion):synchronized 能够保证在同一时间只有一个线程可以执行被 synchronized 保护的代码块,其他线程必须等待当前线程释放锁后才能执行。
synchronized的使用
在Java中,synchronized 可以用来修饰方法或代码块,以实现线程的同步。
- 修饰方法:
public synchronized void method() { // 同步代码 }
上述方法被 synchronized
修饰后,整个方法体被视为一个临界区,只能被一个线程执行,其他线程需要等待。
2.修饰代码块:
public void someMethod() { synchronized (this) { // 同步代码 } }
在代码块中,括号中的对象(这里是 this
)是锁定对象,同一时间只有一个线程可以获取该对象的锁执行代码块中的内容。
synchronized的锁机制
Java中的synchronized锁机制主要涉及以下几个概念:
-
对象锁:当使用 synchronized 修饰一个方法或代码块时,会以对象作为锁。对于非静态方法,锁是实例对象本身;对于静态方法,锁是类的 Class 对象。
-
内置锁(Intrinsic Lock):也称为监视器锁(Monitor Lock),每个Java对象都有一个内置锁。当线程进入 synchronized 方法或代码块时,它会尝试获取对象的内置锁,获取成功后执行代码,执行完毕或发生异常时释放锁。
-
可重入性:Java中的 synchronized 是可重入的,即同一个线程可以重复获取同一个锁,而不会造成死锁。这种机制允许线程在持有锁的情况下调用自身类中的其他 synchronized 方法或代码块。
-
锁的释放:synchronized 在退出 synchronized 方法、代码块或者发生异常时会自动释放锁,确保其他线程可以获取锁并执行。
-
等待通知机制:通过
wait()
、notify()
和notifyAll()
方法,可以实现线程之间的协作,等待某些条件满足后再执行,这些方法必须在 synchronized 方法或代码块中调用,因为它们依赖于对象的监视器锁。
总之,synchronized 是Java中最基本的用于线程同步的机制,通过对象锁和内置锁实现了线程的互斥访问和可见性保证,是多线程编程中常用的关键字之一。