【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() 
     :
     释放同步锁。 
    
 
    
     使用如下: 
     ![]() 
    
 
    
     
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号