线程同步机制

本文详细介绍了Java线程同步机制,包括锁的概念、内存屏障、重入、内存发布与逸出,以及线程封闭技术。锁是通过互斥来保证原子性、可见性和有序性,确保线程安全。内存屏障在锁的实现中起关键作用,而可重入锁允许线程重复获取已持有的锁。发布与逸出可能导致线程安全问题,正确使用final、static和静态初始化器可以实现安全发布。线程封闭技术如栈封闭和ThreadLocal避免了共享数据的同步需求。
摘要由CSDN通过智能技术生成

 

 

一、线程同步机制

从广义上说,Java平台提供的线程同步机制包括锁、volatile关键字、final关键字、static关键字和一些相关的API,如Object.wait( )/.notify( )等

 

1、锁的概述和概念:

a 线程安全问题的产生:

多个线程并发访问共享变量、共享资源;

解决办法:

一个共享变量或者资源只能被一个线程访问,访问结束后其他线程才能访问(用锁)。

 

b、用锁保护状态:

1、对于可能被多个线程同时访问的可变状态变量(比如银行总账户),在访问它时都需要持有同一个锁,在这种情况下,我们称状态变量是有这个锁保护的。

2、每个共享的和可变的变量都应该只有一个锁来保护,从而使维护人员知道是哪一个锁。

3、对于每个包含多个变量的不变性条件,期中涉及的所以变量都需要由同一个锁来保护。

 

  • 许多线程安全类使用的加锁模式是,将可变状态都封装在对象内部,并通过对象的内置锁对所有访问可变状态的代码进行同步
  • 每个对象都有一个内置锁,只是为了免去显式地创建锁对象

 

c、锁的几个概念

锁的争用:锁可以被看做多线程程序访问共享数据时所持有的一种排他性资源

锁的调度:包括公平调度策略和非公平调度策略。内部锁属于非公平锁;显示锁则两者都支持。

锁的粒度:一个锁保护的共享数据的大小称粒度。锁的粒度过粗会导致线程在申请锁的时候需要进行不必要的等待,影响性能。

锁的开销:锁的开销主要包括锁的申请和释放产生的开销,锁可能导致上下文切换,开销主要是处理器时间。

锁可能导致的问题:

a.锁泄漏:指一个线程获得锁之后,由于程序的错误,致使该锁一直无法被释放而导致其他线程一直无法获得该锁的现象。

b.锁的不正当使用还会导致死锁、锁死等线程活性故障

 

d、锁的作用:

保护共享数据以实现线程安全,包括保障原子性、可见性和有序性(原子性和可见性>>有序性)

原子性:锁通过互斥来保障原子性,互斥是指一个锁一次只能被一个线程所持有,所以,临界区代码只能被一个线程执行,即保障了原子性。

可见性:通过写线程冲刷处理器缓存和读线程刷新处理器缓存实现。获得锁之后,需要刷新处理器缓存,使得前面写线程所做的更新可以同步到本线程。释放锁需要冲刷处理器缓存,使得当前线程对共享数据的改变可以被推送到下一个线程处理器的高速缓冲中。

有序性:写线程在临界区中所执行的一系列操作在读线程所执行的临界区看起来像是完全按照源代码顺序执行的。但是并不能保证不重排,只是重排不会影响。

 

锁在保证线程安全的同时满足三大条件,那么我们必须遵守:

1.线程访问同一组数据的时候必须使用同一个锁

2.线程中任意的一个线程,即使其仅仅是你读取这组共享数据而没有对其进行更新的话,也需要在读取时持有相应的锁。

 

锁其实就是把本来并发(未使用锁)的线程改成串行(使用锁)。

 

e、锁的适用场景

        • check-then-act操作:一个线程读取共享数据并在此基础上决定下个操作是什么。
        • r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值