【Java】线程安全
2.1 线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样
的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
我们通过一个案例,演示线程的安全问题:
电影院要卖票,我们模拟电影院的卖票过程。假设要播放的电影是
“
葫芦娃大战奥特曼
”
,本次电影的座位共
100
个
(
本场电影只能卖
100
张票
)
。
我们来模拟电影院的售票窗口,实现多个窗口同时卖
“
葫芦娃大战奥特曼
”
这场电影票
(
多个窗口一起卖这
100
张票
)
需要窗口,采用线程对象来模拟;需要票,
Runnable
接口子类来模拟
模拟票:

测试类:
结果中有一部分这样现象:
发现程序出现了两个问题:
1.
相同的票数
,
比如
5
这张票被卖了两回。
2.
不存在的票,比如
0
票与
-1
票,是不存在的。
这种问题,几个窗口
(
线程
)
票数不同步了,这种问题称为线程不安全。
线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写
操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,
否则的话就可能影响线程安全。
2.2 线程同步
当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。
要解决上述多线程并发访问一个资源的安全性问题
:
也就是解决重复票与不存在票问题,
Java
中提供了同步机制
(
synchronized
)
来解决。
根据案例简述:

为了保证每个线程都能正常执行原子操作
,Java
引入了线程同步机制。
那么怎么去使用呢?有三种方式完成同步操作:
1.
同步代码块。
2.
同步方法。
3.
锁机制。
2.3 同步代码块
同步代码块
:
synchronized
关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。
格式:

同步锁
:
对象的同步锁只是一个概念
,
可以想象为在对象上标记了一个锁
.
1.
锁对象 可以是任意类型。
2.
多个线程对象 要使用同一把锁。
注意
:
在任何时候
,
最多允许一个线程拥有同步锁
,
谁拿到锁就进入代码块
,
其他的线程只能在外等着
(BLOCKED)
。
使用同步代码块解决代码:

当使用了同步代码块后,上述的线程的安全问题,解决了。
2.4 同步方法
同步方法
:
使用
synchronized
修饰的方法
,
就叫做同步方法
,
保证
A
线程执行该方法的时候
,
其他线程只能在方法外
等着。
格式:

同步锁是谁
?
对于非
static
方法
,
同步锁就是
this
。
对于
static
方法
,
我们使用当前方法所在类的字节码对象
(
类名
.class)
。
使用同步方法代码如下:

2.5 Lock锁
java.util.concurrent.locks.Lock
机制提供了比
synchronized
代码块和
synchronized
方法更广泛的锁定操作
,
同步代码块
/
同步方法具有的功能
Lock
都有
,
除此之外更强大
,
更体现面向对象。
Lock
锁也称同步锁,加锁与释放锁方法化了,如下:
public void lock()
:
加同步锁。
public void unlock()
:
释放同步锁。
使用如下:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!