java 线程(五)线程安全 Lock接口

 

package cn.sasa.demo3;

import java.util.concurrent.ExecutionException;

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建Runnable接口实现类对象
        Ticket t = new Ticket();
        //创建3个Thread类对象,传递Runnable接口实现类
        Thread t0 = new Thread(t);
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        
        t0.start();
        t1.start();
        t2.start();
        t3.start();
        /**
          * 线程安全问题一般发生在:
          * 多线程并发访问同一个数据资源
         *  
         *  通过线程休眠,发现了安全问题
         *   
         *   解决安全问题:
         *  ------------------------------------ 方式一------------------------------
         *   同步代码块
         *   synchronized(任意对象){
         *           线程要操作的共享数据
         *   }
         *   同步代码块中的锁对象可以是任意对象,
         *   但多线程时,要使用同一个锁对象才能够保证线程安全性
         *   
         *    ------------------------------------ 方式二------------------------------
         *   同步方法   在方法声明上加入同步关键字
         *   eg :
         *   private synchronized void func(){
         *       ...
         *   }
         *   同步方法中的对象锁,是本类对象引用 this
         *   如果方法是静态的,锁是本类.class属性
         *   
         *    ------------------------------------ 方式三------------------------------
         *   jdk 1.5之后 Lock接口
         *   private Lock lock = new ReentrantLock();
         *   lock.lock();
         *   lock.unlock();
         */
        
        
    }
}

 

package cn.sasa.demo3;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements Runnable {
    //定义出售的票源
    private int ticket = 100;
    
    //jdk 1.5之后 可用接口Lock 创建锁对象
    private Lock lock = new ReentrantLock();
    
    public void run(){ 
        int flag = 100;
      while(flag > 0){
          //获取锁
          lock.lock();
          buyTickets();
          //释放锁
          lock.unlock();
          flag --;
      }
    }
   
    private  void buyTickets() {
        if( ticket > 0){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" 出售第 "+ticket--);
          }
    }
}

 

posted @ 2018-12-29 10:23  SasaL  Views(289)  Comments(0Edit  收藏  举报