线程同步的几个方法

前言

在做程序员的这俩年内总是在向框架,前沿技术赶着学。现在回顾这段跑着的路程,让我觉得应该慢下来去将自己的过往夯实,再向大厦前行,在这几年的编程过程中发现线程的使用是非常常见的,那么废话不多说直接上正文。

线程同步

我们可能在不同的程度知道,在不同的线程针对一个资源的时候,如果说是对资源进行简单的的读取,那么就不会有什么大问题,但是如果对这个资源进行修改的话,那么就会导致资源冲突

并发的情况下面,指令执行的先后顺序由内核决定,那么用我们理解的语言概括一下就是:计算机自己都无法预测我会先执行哪一个线程任务。那么为了解决这个问题我们常用的解决方法就是将其化成一个原子级事务,那么这个事情也就迎刃而解了。

词 义 解 释 \color{#FF0000}{词义解释}
并发:并发是指俩个或者多个事件在同一个时间间隔发生
并行:并行是指俩个或者多个事件在同一时间发生
那么对于多线程的程序来讲,同步的含义就是:在同一个时间内只允许一个线程进行资源访问,那么就有以下几种方法实现:

  • 互斥锁
  • 条件变量
  • 读写锁
  • 信号量

互斥锁

互斥锁 是最常见的线程同步方式,它是一种特殊的变量,它有 lock 和 unlock 两种状态,一旦获取,就会上锁,且只能由该线程解锁,期间,其他线程无法获取
互 斥 锁 模 型 \color{#FF0000}{互斥锁模型}
在这里插入图片描述
当线程进入临界区之前,首先尝试加锁,如果成功,可以进去临界区,如果失败,需要等待。当临界区的代码被执行完毕或者发生异常时,线程释放锁。

当然如果说世界总是这么简单就好了,上面的模型虽然直观但是过于简单,我们现在来考虑以下俩个问题;

  1. 我们锁的是什么?
  2. 我们保护的又是什么?

在我们现实时世界里面锁和锁要保护的资源是有对应关系的,通俗的来说讲,你用你家的锁保护你家的东西,我用我家的锁保护我家的东西。
在并发编程里面我们也要学着去探究锁和资源是否也有着这层关系

改 进 互 斥 锁 模 型 \color{#FF0000}{改进互斥锁模型}

在这里插入图片描述

语法

public class test {

	// 修饰实例方法
	synchronized void Data() {
		// 业务代码
	}
	
	// 修饰静态方法
	synchronized static void updateData() {
		// 业务代码
	}
	
	// 修饰代码块
	Object obj = new Object();
	
	void createData() {
		synchronized(obj) {
			// 业务代码
		}
	}
}

我们不用担心执行加锁操作后,忘了解锁操作,因为Java编译器已经自动为我们在synchronized关键字修改的方法或者代码块前后添加了加锁和解锁逻辑。

锁和受保护的资源关系

通俗的来说锁和受保护的资源之间是N:1的关系

  • 一个锁可以保护多个对象
  • 一个受保护的资源上只能有一个锁

我们可以用车票来做类比,其中车上面固定的座位比做资源,那么一个车票对应的就是一个座位,如果遇到的是包车作为这个对象,那么一张车票就对应着一车的座位,就不会有一个座位对应着多张车票的情况。

同理:在互斥锁的场景下,如果两个锁使用了不同的锁对象,那么这两个所对应的临界区不是互斥的。这一点很重要,如果忽视他的话,那么就会引发很多并发的问题。

细粒度锁

做一个简单的描述:银行业务中,修改密码,以及取钱业务,从业务来看这俩块业务没有关联,是可以并行的,那么我们就可以创建各自的互斥锁对资源进行保护,那么这样的话,这俩个业务就不会互相影响了,这样的锁也被称为细粒度锁

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

敏姐儿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值