【单机和分布式环境下的多线程并发访问的安全性问题】

【单机和分布式环境下的多线程并发访问的安全性问题】

有时间就稍微记录一下。【持续更新】

多线程并发访问的安全性问题

首先要知道的是:多线程安全性问题产生的原因是什么?

多线程并发访问是指当多个线程无序的访问同一个共享资源时,这个线程就受到了“多个线程的并发访问”。

多线程并发访问的安全问题

在出现多个线程并发访问的时候,这时就有可能产生并发访问的安全性问题,可能会导致共享资源的最后结果不是我们期望的结果。(此处不做具体演示)

该如何解决多线程并发访问的安全问题呢?

利用【线程同步】可以解决多线程并发访问的安全性问题。

线程同步的方式:

在单机环境中:

  1. synchronized同步方法
  2. synchronized同步代码块
  3. Lock锁(JDK1.5以后提供的显示锁,通常使用Lock接口的实现类ReentrantLock,它包含了:公平锁、非公平锁、可重入锁、读写锁 等更多更强大的功能)

注:
(1)synchronized锁属于jvm级别的锁,当代码执行完之后,JVM底层会自动释放锁。
(2)如果使用ReentrantLock,需要在finally代码块中手动释放锁。使用Lock显示锁的方式,解决线程安全问题,给开发人员提供了更多的灵活性。
(3)在单机的情况下,使用synchronized和Lock保证线程安全是没有问题的。

同步方法

我这里写一个方法:

public synchronized int getNumber(){
//被同步的代码。。
}

当一个线程进入到方法时,会立即锁死这个方法,其他线程会在外边等待。为啥呢?因为在加了synchronized同步锁之后,其他线程进不来,当内部的线程线程执行完之后,其他的线程才能进来,以此类推。这样可以保证每个线程可以完整的执行完,这样就避免了多线程并发访问的安全问题。

同步代码块

通过锁对象,来完成对线程的同步。

private Object obj = new Object();
public synchronized int getNumber(){
  synchronized(obj){
   //被同步的代码。。
  }
}

这里是通过锁对象,保证多个线程进来后,访问到的都是一个对象,来完成对线程的同步。它可以出现在方法内部,一个方法内可以有多个同步代码块。
Lock锁
Lock它是一个接口,是在JDK1.5以后新出的锁。这里简单举个例子,实际工作中不要以此为标准。

Lock lock = new Lock的实现类
public synchronized int getNumber(){
  lock.lock();//加锁
  try{
     //被同步的代码。。
  }finally{
    lock.unlock();//解锁
     }
  }

在分布式的环境中

如果是在分布式环境中,某应用部署了多个节点,每个节点可以使用synchronizedLock保证线程安全,但是不同节点之间是没办法保证线程安全的。

  1. redis分布式锁
  2. zookeepper分布式锁

个人更推荐使用redis分布式锁,其效率相对来说更高一些

这里我详细说一下自己对redis分布式锁的简单理解。
实现redis分布式锁的方式我知道的有两种方式,使用jedis实现分布式锁可以很好的让我们去理解他的实现方式,但是redission开源之后,简化了redis分布式锁实现的复杂度(只是我们用起来简化了,内部还是原来的样子)。
jedis实现:
1.生成一个UUID
2.调用setNx方法拿到锁,设置这把锁的key对应的value(这个value的值就是第一步生成的UUID),同时设置他的有效期。setNx方法保证了它的原子性。
3.接下来要注意的问题点就是释放锁的时候,需要保证他的原子性。可以借助于lua脚本来实现。这也是为什么在第一步生成UUID的原因。

友情提示,上面的几点还存在一些问题。涉及到redis的一些特性的问题。如果想详细了解redis的分布式锁,可以自己去动手学习。

在实际工作中,我们可以使用redission来实现。为啥? 因为它简化了redis分布式锁的实现。仅仅几行代码就能搞定。但是如果去看它的源码会发现,redission是做了封装,他内部实现还是和上面提到的jedis的实现方式一样, 同时也将lua脚本封装到了代码中。

···························································································································································

持续更新,共同进步!

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

坐怀不乱丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值