多线程——synchronized关键字

在我们的多线程中,我们还需要去了解一个很重要的关键字,那就是synchronized关键字,那我们就来具体聊一聊为什么要创建这样一个关键字吧!

synchronized关键字的意义

在我们的日常开发当中,使用多线程都是使用并发编程,可能会出现线程安全问题,那这个时候我们就需要用到synchronized来解决。比如说在多线程环境下,如果多个线程同时访问和修改共享的数据或资源,可能会导致竞态条件,从而产生不可预测的结果或数据错误。使用 synchronized 可以保证同一时刻只有一个线程可以进入同步代码块或方法,避免竞态条件的发生。还有一种情况就是我们的线程会将数据变更刷新到内存当中,但我们的将数据录入到内存当中的这段时间会有其他线程也进数据的读取,我们录入的速度没有其他线程的读取速度快,就会造成数据可见性的问题,这个时候就会有线程安全问题,关于线程安全,我们以后会有更详细的解释。

synchronized的特性

互斥

synchronized 会起到互斥效果 , 某个线程执行到某个对象的 synchronized 中时 , 其他线程如果也执行到
同一个对象 synchronized 就会 阻塞等待
进入 synchronized 修饰的代码块 , 相当于 加锁
退出 synchronized 修饰的代码块 , 相当于 解锁
可以粗略理解成, 每个对象在内存中存储的时候, 都存有一块内存表示当前的 "锁定" 状态(类似于厕
所的 "有人/无人").
如果当前是 "无人" 状态, 那么就可以使用, 使用时需要设为 "有人" 状态.
如果当前是 "有人" 状态, 那么其他人无法使用, 只能排队

刷新内存

synchronized 的工作过程:
1. 获得互斥锁
2. 从主内存拷贝变量的最新副本到工作的内存
3. 执行代码
4. 将更改后的共享变量的值刷新到主内存
5. 释放互斥锁

可重入

synchronized 同步块对同一条线程来说是可重入的,不会出现自己把自己锁死的问题。

可重入特性的原理:

同一个线程可以多次获取同一把锁当一个线程持有某个锁时,如果这个线程再次试图获取同一把锁,它会成功获取,而不会被自己持有的锁所阻塞。这种情况下,锁计数器会递增。

锁持有计数器:每个锁关联一个持有计数器(lock count),用于记录某个线程获取该锁的次数。当线程首次获取锁时,计数器从0变为1。每当同一个线程再次获取该锁时,计数器递增。只有当计数器归零时,锁才会被完全释放。

释放锁的条件:锁只有在持有线程完全释放它时,才能被其他线程获取。这意味着同一个线程在持有锁期间,可以多次进入同步块或方法,而不会被自己的锁持有所阻塞。

public class ReentrantExample {
    public synchronized void outer() {
        inner();
        // 外部同步方法可以调用内部同步方法
    }

    public synchronized void inner() {
        // 内部同步方法
    }
}

在这个示例中,outer() 方法和 inner() 方法都是同步方法,并且它们都使用了 synchronized 关键字来保证线程安全。如果一个线程已经持有了 ReentrantExample 对象的锁(通过调用 outer() 方法),那么它可以继续调用 inner() 方法,而无需重新获取锁,因为它已经持有了该锁的计数。 

synchronized 使用示例

直接修饰普通方法 : 锁的 SynchronizedDemo 对象
public class SynchronizedDemo {
    public synchronized void methond() {
   }
}
修饰静态方法 : 锁的 SynchronizedDemo 类的对象
public class SynchronizedDemo {
    public synchronized static void method() {
   }
}
修饰代码块 : 明确指定锁哪个对象
// 锁当前对象
public class SynchronizedDemo {
    public void method() {
        synchronized (this) {
            
       }
   }
}

// 锁类对象
public class SynchronizedDemo {
    public void method() {
        synchronized (SynchronizedDemo.class) {
       }
   }
}

小结

总结来说,synchronized关键字是Java中最基本且简单的线程同步机制,通过对对象的锁定来保证多线程访问的安全性,但在某些情况下可能需要考虑其对性能的影响以及可替代的更灵活的锁实现方式。

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

comerun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值