16.5.2 同步代码块
16.5.2 同步代码块
同步代码块
Java
的多线程支持引入了同步监视器来解决同步问题,**使用同步监视器的通用方法就是同步代码块**。
同步代码块的语法格式
1 | synchronized(object) |
什么是同步监视器
synchronized
关键字后面的括号里的参数object
就是同步监视器
同步代码块的含义
同步代码块的含义是:
线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。
任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。
同步监视器的选择标准
虽然Java
程序允许使用任何对象作为同步监视器,但同步监视器的目的是阻止两个线程对同一个共享资源
进行并发访问,因此通常推荐使用可能被并发访问的共享资源充当同步监视器。
程序 使用同步代码块 同步取钱
对于上面的取钱模拟程序,应该考虑使用账户(account
)作为同步监视器,把程序修改成如下形式。
1 | public class DrawThread extends Thread { |
上面程序使用synchronized
将run()
方法里的方法体修改成同步代码块
,该同步代码块的同步监视器是account
对象,这样的做法符合”加锁→修改→释放锁”的逻辑。
加锁 修改 释放锁
任何线程在修改指定资源之前,
- 首先对该资源加锁,在加锁期间其他线程无法修改该资源,
- 当该线程修改完成后,
- 该线程释放对该资源的锁定。
通过这种方式就可以保证并发线程在任一时刻只有一个线程可以进入修改共享资源的代码区(也被称为临界区),所以同一时刻最多只有一个线程处于临界区内,从而保证了线程的安全性。
将DrawThread
修改为上面所示的情形之后,多次运行该程序,总可以看到如下的运行结果:
1 | 甲取钱成功!吐出钞票:800.0 |