未加锁时容易出现重复买票情况
代码
public class Ticket12306 implements Runnable{
// 票数
private int ticketNums = 10;
@Override
public 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;
@Override
public 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