Synchronized 关键字

Synchronized 关键字

synchronized 同步方法支持一种简单的策略来防止线程干扰和内存一致性错误:即如果一个对象对多个线程可见,则该对象变量的所有读写操作都是通过同步方法完成。

synchronized 修饰的代码段,能够保证在同一时刻最多只有一个线程执行,以达到保证并发安全的效果。

用法

1 对象锁

1.1 代码块形式

手动指定锁对象

static final Object LOCK_1 = new Object();

synchronized (LOCK_1) {
    // do method
}
1.2 方法锁形式

synchronized 修饰方法,默认锁对象为this

private synchronized void doMethod() {
    // do method
}

2 类锁

Java 类可能会有很多个对象,但只有1个 Class 对象。类锁,相当于 Class 对象的锁。即类锁只能在同一时刻被一个对象拥有。

2.1 静态方法锁
private static synchronized void doMethod() {
    // do method
}
2.1 synchronized(*.class) 代码块

synchronized 修饰静态的方法或指定锁为 Class 对象

public class SyncClassClass {

    private void doMethod() {
        synchronized (SyncClassClass.class) {
            // do method
        }
    }
}

多线程访问同步方法的面试点

1 多线程同时访问一个对象的synchronized方法

多线程会发生对同步方法锁的竞争,当一个线程竞争到锁时,其余线程会阻塞等待。

2 多线程访问的是两个对象的synchronized方法

因为对象锁的方法锁,默认为this当前实例对象,因此每一个线程的锁相互独立,并不互斥,会发生并发问题。

3 多线程同时访问一个对象的静态synchronized方法

多线程会发生对同步方法锁的竞争,当一个线程竞争到锁时,其余线程会阻塞等待。

4 多线程同时访问一个对象的synchronized方法与非同步方法

synchronized 只作用于同步方法,非同步方法不受影响,因此同步方法与非同步方法可以并行。

5 多线程同时访问一个对象的不同的synchronized方法

因为对象锁的方法锁,默认为this当前实例对象,因此对于同一个实例对象,同步锁会发生互斥,不同的同步方法将会串行执行。

6 多线程同时访问一个对象的静态synchronized与非静态synchronized方法

静态synchronized锁为类锁,非静态synchronized锁为对象锁,类锁与对象锁之间不会发生互斥,因此静态synchronized方法和非静态synchronized方法将会同时执行。

7 synchronized方法抛异常后,会释放锁

  • synchronized :抛异常后会自动释放锁。
  • Lock :抛异常不会主动释放锁。

性质

1 可重入

指同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁。

好处:避免死锁,提升封装性。

粒度:线程非调用。

原理:利用加锁次数计数器。即线程第一次给对象加锁的时候,计数变为1,每当这个相同的线程在此对象上再次获得锁时,计数会递增;每当任务离开时,计数会递减,当计数为0时,锁被完全释放。

2 不可中断

当一个锁被某一线程持有时,其余线程只能阻塞等待该线程释放锁。如果该线程不释放锁,则其余线程只能永远等待。

内存可见性

内存可见性

缺点

  • 效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程。
  • 不够灵活:加锁和释放的时机单一,每个锁仅有单一的条件。
  • 无法知道是否成功获取到锁

参考

  1. Java高并发之魂:synchronized深度解析
  2. GitHub
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
synchronized关键字Java中用于实现线程同步关键字。它可以用来修饰方法或代码块,以确保在多线程环境下的安全性。 synchronized关键字的使用有以下几点需要注意: 1. synchronized是一种重量级的操作,会影响性能。因此,在使用synchronized时应尽可能减小同步块的范围,避免锁的竞争。 2. synchronized锁的范围应尽量小,只保护必要的代码块,避免对整个方法或对象进行锁定。这样可以提高程序的并发性能。 3. synchronized锁定的对象不应该被修改,否则可能会导致死锁的发生。因此,在使用synchronized时需要谨慎处理锁定的对象。 4. 在使用synchronized时,需要考虑线程间的协调和通信,以避免死锁和活锁的发生。这可以通过合理设计程序逻辑和使用其他同步机制来实现。 总的来说,synchronized关键字是一种常用的线程同步机制,可以确保在多线程环境下的数据安全性和一致性。但是在使用时需要注意性能问题和锁的范围,以及避免死锁和活锁的发生。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Synchronized 关键字详解](https://blog.csdn.net/swadian2008/article/details/99328700)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [举例讲解Javasynchronized关键字的用法](https://download.csdn.net/download/weixin_38724611/12798175)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值