未加锁时容易出现重复买票情况
代码
public class Ticket12306 implements Runnable{// 票数private int ticketNums = 10;@Overridepublic void run() {while (true){if (ticketNums>0){System.out.println(Thread.currentThread() + "抢到了第" + ticketNums + "张票");ticketNums--;}}}
}
public class Main {public static void main(String[] args) {Ticket12306 ticket = new Ticket12306();// 模拟多个线程抢票Thread thread1 = new Thread(ticket, "窗口1");Thread thread2 = new Thread(ticket, "窗口2");thread1.start();thread2.start();}
}
结果
加分布式锁后
public class Ticket12306 implements Runnable{// 票数private int ticketNums = 10;public Ticket12306() {// 重试策略ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(3000, 10);CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.106.140:2181").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(15 * 1000).retryPolicy(retryPolicy).build();// 开启连接client.start();lock = new InterProcessMutex(client,"/lock");}private InterProcessMutex lock;@Overridepublic void run() {while (true){try {// 获取锁lock.acquire(3, TimeUnit.SECONDS);if (ticketNums>0){System.out.println(Thread.currentThread() + "抢到了第" + ticketNums + "张票");ticketNums--;}// 解锁} catch (Exception e) {throw new RuntimeException(e);} finally {try {lock.release();} catch (Exception e) {throw new RuntimeException(e);}}}}
}
出现问题
期间还遇到了一个小插曲,这里顺便记录下。
在连接zookeeper时候出现下面这个错误,刚开始以为是服务端zookeeper出问题了,但是检查后发现没问题,在服务端可正常创建、修改节点信息。
解决方案:关闭服务器防火墙
systemctl stop firewalld