6、线程 的安全问题 和 解决办法1之 同步代码块
窗口买票,有3个窗口,一共有票100张
执行结果:
显示有 重票的 问题,这个是线程安全问题,
因为 假设窗口(线程)1 先进来 票号为1 ,然后睡了100毫秒这时候它暂时 没有往下走代码,票数暂时没有减一,所以票号依然是1
刚好这时候假设 窗口(线程)2 进来 ,票号为1 ,睡了100毫秒没有往下走代码,暂时票数没有 减一操作,线程3同样。
所以3个线程都 卖了1号票,共同票就是这个原因。
解决办法就是 ,每个线程拿到 操作的时候,上一把锁,
这时候,别的线程 不能进行 卖票的操作,只能等待正在使用资源的线程 操作完 释放锁后,
CPU再分配给 别的线程 执行权 进行操作
解决办法有 3 种 ,
1、同步代码块 2、同步方法 3、Lock锁方式
同步代码块 方式的 语法 :
synchronized (this) { //需要被同步的代码 } //说明:1. 需要被同步的代码 就是 操作共享数据的代码 2. 共享数据 : 多个线程共同操作的变量。比如: ticket就是共享数据 3. 参数this 是同步监视器,俗称:锁 任何一个类的对象都可以充当锁,锁必须是唯一的,只能有一把 (补充:类 也是对象的一种)(隐藏要求:多个线程必须 共用同一把锁)
(这里是同步代码块 ,若是 同步方法 则慎用this)
用 同步代码块 解决 实现方式创建线程的 线程安全问题:
执行结果如下:(已解决重票 & 错票 的线程安全问题)
用 同步代码块 解决 继承方式创建线程的 线程安全问题:
执行结果: