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)

同步代码块 解决 实现方式创建线程的 线程安全问题:

执行结果如下:(已解决重票 & 错票 的线程安全问题)

用 同步代码块 解决 继承方式创建线程的 线程安全问题:

 

 执行结果: