深入理解Java synchronized机制

5星 · 超过95%的资源 需积分: 10 41 下载量 113 浏览量 更新于2024-09-17 收藏 18KB TXT 举报
"JAVA synchronized详解" 在Java编程中,`synchronized`关键字是用于实现多线程环境中的线程同步,防止多个线程同时访问共享资源,从而避免数据的不一致性。它确保了同一时间只有一个线程可以执行特定的代码块或方法。 一、synchronized的两种使用方式 1. **同步方法**: 当`synchronized`关键字修饰一个方法时,整个方法体被视为一个同步块。这意味着每次只有一个线程可以调用这个方法,其他线程必须等待当前线程执行完毕才能继续。 示例代码: ```java public synchronized void method() { // 代码块 } ``` 2. **同步代码块**: 同步代码块允许我们指定要锁定的对象,这样只有获取到该对象锁的线程才能执行同步块内的代码。 示例代码: ```java public void method() { synchronized (object) { // 代码块 } } ``` 二、同步的原理与作用 `synchronized`关键字通过 JVM 的锁机制实现,它基于进入和退出 Monitor(监视器锁)对象来完成。Monitor 是每个对象都有的内置锁,也称为 intrinsic lock 或 monitor lock。 三、线程的互斥与可见性保证 1. **互斥**:当一个线程进入同步代码块后,其他线程无法再进入,直到当前线程执行完毕并释放锁。 2. **可见性**:在同步块内修改的变量,对其他线程是可见的,因为同步保证了数据的更新会被其他线程感知。 四、synchronized的注意事项 1. **死锁**:如果多个线程互相持有对方需要的锁,可能会导致死锁。因此在设计同步代码时需谨慎,避免循环等待。 2. **锁升级**:JVM会尝试优化同步,对于轻量级锁(如 CAS 操作),如果竞争激烈,会升级为重量级锁(即 Monitor 锁)。这会影响性能,所以在设计同步策略时应尽量减少锁的使用。 3. **锁的粒度**:同步的粒度越细,效率越高,但过度细化可能导致锁的管理开销增大。因此,应根据具体需求权衡锁的粒度。 五、实例分析 1. **同一对象的不同同步方法**: 在给定的例子中,`Thread1`类的`run()`方法被`synchronized`修饰,意味着两个线程 `ta` 和 `tb` 分别启动后,它们会依次执行该方法,不会出现交错打印。这就是所谓的线程间的互斥。 2. **不同对象的相同同步方法**: `Thread2`类展示了不同对象间的同步。即使两个线程`m4t1()`方法都在同步块内部,但由于它们分别属于不同的对象,因此它们可以同时执行,不互相影响。 六、总结 `synchronized`关键字是Java多线程编程中至关重要的工具,它提供了互斥和可见性的保证。正确使用它可以有效地避免并发问题,但过度依赖或不恰当使用则可能导致性能下降或其他并发问题。在编写多线程程序时,需要结合业务场景,合理地设计同步策略。