静态同步方法和解决线程安全问题_Lock锁
静态的同步方法锁对象是谁?不能是this
this是创建对象之后产生的,静态方法优先于对象
静态方法的锁对象是本类的cLass属性-->class文件对象(反射)
卖票案例出现了线程安全问题
卖出了不存在的票和重复的票
解决线程安全问题的三种方案:使用lock锁
java.util.concurrent.locks.Lock接口
Lock实现提供了比使用synchronized方法和语句获得更广泛的锁定操作
Lock接口中的方法
void Lock()获取锁
void unlock() 释放锁
java.util.concurrent.Locks.ReentrantLock implements Lock接口
使用步骤
1.在成员位置创建一个ReentrantLock对象
2.在有可能会出现安全问题的代码前调用Lock接口中的方法Lock获取锁
3.有可能会出现安全问题的代码后调用Lock接口中的方法unlock关闭所
public class RunnableImpl implements Runnable { // 定义一个多线程共享资源 private int ticket = 100; // 1.在成员位置创建一个ReentrantLock对象 Lock l = new ReentrantLock(); // 设置线程任务 卖票 @Override public void run() { // 使用死循环 让卖票操作重复操作 while (true) { // 2.在有可能会出现安全问题的代码前调用Lock接口中的方法Lock获取锁 l.lock(); // 先判断票是否存在 if (ticket > 0) { // 提高安全问题出现的概率,让程序睡眠 try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票"); ticket--; } l.unlock(); } } }
/** * 模拟卖票案例 * 创建3个线程,同时开启,对共享的票进行出售 * */ public class Demo01Ticket { public static void main(String[] args) { // 创建Runnable接口的实现类 Runnable run = new RunnableImpl(); // 创建Thread类对象 构造方法中传递Runnable接口的实现类对象 Thread t = new Thread(run); Thread t1 = new Thread(run); Thread t2 = new Thread(run); // 调用start方法开启多线程 t.start(); t1.start(); t2.start(); } }