Lock锁
卖票案例出现了线程安全问题(卖出去不存在的票和重复的票)
第三种解决方案,使用Lock锁
java.util.concurrent.locks
Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作。
它们允许更灵活的结构化,可能具有完全不同的属性,并且可以支持多个相关联的对象Condition 。
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;
//在成员位置创建一个Reentrantlock对象
Lock l= new ReentrantLock();
@Override
public void run() {
while (true)
{
l.lock();
if(ticket>0)
{
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票!");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//在可能会出现安全问题的代码后面调用Lock接口中的方法Unlock释放锁
l.unlock();//无论程序是否异常,都会把锁释放!
}
}
}
}
}
测试类代码:
public class Demo01Ticket {
public static void main(String[] args) {
RunnableImpl run=new RunnableImpl();
Thread t0=new Thread(run);
Thread t1=new Thread(run);
Thread t2=new Thread(run);
//调用start,开启多线程
t0.start();
t1.start();
t2.start();
}
}
实现效果:
Thread-0正在卖第100张票!
Thread-0正在卖第99张票!
Thread-0正在卖第98张票!
Thread-0正在卖第97张票!
Thread-0正在卖第96张票!
Thread-0正在卖第95张票!
Thread-0正在卖第94张票!