多线程—synchronized

本文详细介绍了Java中的synchronized关键字,如何保证临界区的原子性和线程同步。通过对象锁实现互斥访问,防止竞态条件,确保代码执行的完整性。synchronized可应用于代码块和方法,静态方法则锁定类对象。当一个线程持有对象锁后,其他线程将被阻塞,直到锁被释放。临界区是指一次仅允许一个线程访问的代码段,防止数据不一致。
摘要由CSDN通过智能技术生成

synchronized俗称对象锁,它采用互斥的方式让同一时刻至多只有一个线程持有对象锁,其他线程想获取这个对象锁时就会阻塞,这样就不用担心上下文切换。

关系:synchronized使用对象锁保证了临界区(下面有介绍)内代码的原子性(完整性),临界区内的代码对外是不可分割的,不会被线程上下文切换所打断

注意:同一个临界区,线程访问的对象锁应该是一致的,就好比进入同一个房间,钥匙必须都是那一把,才能达到锁住的目的。

Java中互斥和同步都可以采用synchronized来完成,但有区别:

(1)互斥是保证临界区的竞态条件(下面有介绍)发生,同一时刻只能有一个线程执行临界区代码。

(2)同步是由于线程执行的先后顺序不同,需要一个线程等待其他线程运行到某个点(比如获取结果等)。

语法:保证想要执行临界区的线程都要获取括号里面的对象的对象锁。

synchronized(对象)
{
	临界区
}

加在方法上:

//加在方法上,也是锁的对象,锁的是当前方法的对象(this),对整个方法起作用
public synchronized void test(){
	
}

加在静态方法上:

//加在静态方法上,锁的类对象,而不是this对象,对整个方法起作用
public synchronized static void test(){
	
}

场景理解:

A线程获取到synchronized代码块的对象锁后,同时cpu给A线程分配时间片,此时A线程就可以进入到synchronized代码块执行,其它线程要执行synchronized代码块,发现对象锁已经被占用,因此进入BLOCKED阻塞状态;如果A线程没有执行完synchronized代码块,那么它不会释放对象锁(除非调用wait),因此,其它线程也无法进入synchronized代码块执行代码,并且cpu也不会给处在BLOCKED阻塞状态的线程分配时间片,因此下一次会再分配时间片给A线程,直到A线程执行完synchronized代码块,释放对象锁,并且唤醒处在BLOCKED阻塞状态的线程,让其处于RUNNABLE状态,如果此时有多个线程,那么它们将会竞争。

临界区:

临界区表示一种公共资源或共享资源,可以被多个线程使用,但是一次只能有一个线程使用。一旦临界区被线程占用,其他线程像使用临界区就必须等待。

竞态条件(两种):

  1. read-modify-write(读-改-写):例如:i++,先读取值,计算,最后写回。

  2. check-then-act(检测而后行动):例如:if条件判。先取值,然后根据值判断下一步干什么。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

何怀逸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值