一、分布式锁
1、为什么需要锁?(一多二写三互斥)
- 多任务环境中才需要
- 任务都需要对同一共享资源进行写操作;
- 对资源的访问是互斥的
任务通过竞争获取锁才能对该资源进行操作(竞争锁);当有一个任务在对资源进行更新时(占有锁),其他任务都不可以对这个资源进行操作(任务阻塞),直到该任务完成更新(释放锁)。
2、分布式锁方案比较
2、模板方法模式
在父类中编排主流程,将步骤实现延迟到子类去实现。
- 定义锁的接口Lock
- 在AbstractLock模板锁里面实现getLock方法,实现通用的逻辑。
- 不能确实的步骤,作为虚拟方法,甩锅给子类实现。
- 子类只需要聚焦自己的小步骤逻辑,实现tryLock,waitLock,unLock方法
2.1、模板锁的实现代码如下:
public abstract class AbstractTemplate {
public void shopping() {
Map<String,Float> cars = new HashMap();
cars.put("手机",10f);
cars.put("电视",20f);
cars.put("电脑",30f);
checkGoods(cars);//1.清点商品
float mony = calculation(cars);//2计算价格
if(pay(mony)) { //支付
delivery();//如果支付成功送货
}
}
public void checkGoods(Map<String,Float> cars) {
if(cars!=null) {
System.out.print("你购买的了:");
for(String key:cars.keySet()) {
System.out.print(key+" ");
}
System.out.println();
}
}
public float calculation(Map<String,Float> cars) {
float result = 0;
if(cars!=null) {
for(String key:cars.keySet()) {
result += cars.get(key);
}
}
System.out.println("你总共应该支付:"+result);
return result;//钱
}
public abstract boolean pay(Float money) ;
public void delivery() {
System.out.println("请稍等,正在送货中!");
}
}
//实现支付方式
public class WxPayTemplate extends AbstractTemplate{
public boolean pay(Float money) {
System.out.println("hankin使用微信支付了:"+money);
return true;
}
public static void main(String[] args) {
AbstractTemplate at = new WxPayTemplate();
at.shopping();
}
}
代码运行结果:
你购买的了:电脑 手机 电视
你总共应该支付:60.0
hankin使用微信支付了:60.0
请稍等,正在送货中!
2.2、使用锁lock的方式实现
public class OrderNumGenerator {
public static int count = 0;//全局订单id
private java.util.concurrent.locks.Lock lock = new ReentrantLock();
//以lock的方式解决
public String getNumber() {
try {
lock.lock();
SimpleDateFormat simpt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String s = simpt.format(new Date()) + "-" + ++count;
return s;
}finally {
lock.unlock();
}
}
}
//使用多线程模拟生成订单号
public class OrderService implements Runnable {
private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();
private static CountDownLatch countDownLatch = new CountDownLatch(50);
private static List<String> result = new Vector<String>();
public void run() {
try {
countDownLatch.await();
result.add(orderNumGenerator.getNumber());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("####生成唯一订单号###");
OrderService orderService = new OrderService();
for (int i = 0; i < 50; i++) {
new Th