线程安全概念与关键字synchronized

本文深入探讨了线程安全的重要性,并详细解释了Java关键字synchronized的使用,包括锁的对象、锁的本质、实现原理及案例演示。通过案例展示了synchronized如何保证线程同步,防止并发执行时的数据冲突,确保程序的正确性。
摘要由CSDN通过智能技术生成

1:线程安全重要性

并行程序开发的一大关注重点就是线程安全。一 般来说, 程序并行化是为了获得更高的执行效率,但前提是,高效率不能以牺牲正确性为代价。如果程序并行化后,连基本的执行结果的正确性都无法保证,那么并行程序本身也就没有任何意义了。因此,线程安全就是并行程序的根基。大家还记得那个多线程读写long型数据的案例吧!它就是一个典型的反例。但在使用volatile 关键字后,这种错误的情况有所改善。但是,volatile 关键字并不能真正保证线程安全。它只能确保一个线程修改了数据后,其他线程能够看到这个改动。但当两个线程同时修改某一个数据时,仍然会产生冲突

线程安全高到低:不可变>绝对线程安全>相对线程安全>线程兼容>线程对立

2:关键字synchronized

2.1 锁的对象是什么?

synchronized关键字其实是“给某个对象加了把锁”,这个锁究竟加在了什么对象上面?如下面的代码所示,给函数f10、f20加 上synchronized关键字。

class A {
   
public void synchronized f1() {
   .}
public static void synchronized f2() (.)
}

等价于如下代码:

class A{
   
public void f1() {
   
synchroniized(this){
   *}
}
public static void f2() {
   
synchroniized(A.class){
   ..}
}
}
A a= newA()
a.f1();
a.f2();

对于非静态成员函数,锁其实是加在对象a上面的:对于静态成员函数,锁是加在A.class上面的。当然,class 本身也是对象。

这间接回答了关于synchroniized的常见问题:一个静态成员函数和一个非静态成员函数,都加了synchroniized关键字,分别被两个线程调用,它们是否互斥?很显然,因为是两把不同的锁,所以不会互斥。

2.2 锁的本质是什么

无论使用什么编程语言,只要是多线程的,就一定会涉及锁。既然锁如此常见,那么锁的本质到底是什么呢?

如下图所示,多个线程要访问同一个资源。线程就是一段段运行的代码; 资源就是一个变量、一个对象或一个文件等:而锁就是要实现线程对资源的访问控制,保证同一时间只能有一个线程去访问某一个资源。打个比方,线程就是一个个游客,资源就是一 个待参观的房子。这个房子同一时间只允许一个游客进去参观,当一个人出来后下一个人才能进去。而锁,就是这个房子门口的守卫。如果同一时间允许多个游客参观,锁就变成信号量,这点在如下讲述到
JUC——JUC强大辅助类讲解
在这里插入图片描述从程序角度来看,锁其实就是一个“对象”,这个对象要完成以下几件事情:

(1)这个对象内部得有一个标志位(state 变量),记录自己有没有被某个线程占用(也就是记录当前有没有游客已经进入了房子)。最简单的情况是这个:state有0、1两个取值,0表示没有线程占用这个锁,1 表示有某个线程占用了这个锁。

(2)如果这个对象被某个线程占用,它得记录这个线程的thread ID,知道自己是被哪个线程占用了(也就是记录现在是谁在房子里面)。

(3)这个对象还得维护一个thred id list,记录其他所有阻塞的、等待拿这个锁的线程(也就是记录所有在外边等待的游客)。在当前线程释放锁之后(也就是把state从1改回0),从这个thread id list里面取一个线程唤醒。

既然锁是一个“对象”。 要访问的共享资源本身也是个对象。 例如前面的对象a,这两个对象可以合成一个对象。 代码就变成synchronizd(this) {。。},我们要访问的共享资源是对象a,锁也是加在对象a上面的。当然,也可以另外新建个对象, 代码变成synchronizd(obj1){。。。}。这个时候,访问的共享资源是对象a,而锁是加在新建的对象obj1上面的。

资源和锁合为一,使得在 Java 里面,synchronizd关键字可以加在任何对象的成员上面,这意味着ÿ

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值