zookeeper 客户端 Apache curator 分布式锁实操
一、为什么要使用分布式锁:
保证同一时间只有一个客户端可以对共享资源进行操作,这样能有效的做到数据一致性。
二、zooKeeper 实现分布式锁的原理:
三、Apache curator 实现分布式锁:
1、InterProcessMutex 分布式可重入排它锁:
public void interProcessMutexLock(CuratorFramework zkClient) { InterProcessMutex interProcessMutex = new InterProcessMutex(zkClient, basePath); try { //interPRocessMutex.acquire(10,TimeUnit.HOURS) 获取锁。并设置超时时间 if (interProcessMutex.acquire(10, TimeUnit.HOURS)) { try { buyPhone(1); } catch (Exception ex) { System.out.println("异常..."); ex.printStackTrace(); } } // 重入锁 if(interProcessMutex.acquire(10, TimeUnit.HOURS)){ try { buyPhone(1); } catch (Exception ex) { System.out.println("异常...."); ex.printStackTrace(); } finally { //释放锁 interProcessMutex.release(); interProcessMutex.release(); System.out.println("释放锁...."); } } } catch (Exception e) { e.printStackTrace(); }finally { //zkClient.close(); } }
2、InterProcessReadWriteLock 分布式读写锁:
public void interProcessReadWriteLock(CuratorFramework zkClient){ InterProcessReadWriteLock interProcessReadWriteLock = new InterProcessReadWriteLock(zkClient,basePath); InterProcessMutex readLock = interProcessReadWriteLock.readLock(); InterProcessMutex writeLock = interProcessReadWriteLock.writeLock(); /** * 一个负责读操作,一个负责写操作。 * 读操作在写锁没被使用时可同时由多个进程使用,而写锁使用时不允许其他进程读使用。 * 一个拥有写锁的线程可重入读锁,反之不行。 */ try{ /*// 读锁 if(readLock.acquire(10, TimeUnit.HOURS)){ System.out.println("Thread Name is : " + Thread.currentThread().getName()); System.out.println("phone inventory : " + getPhoneInventory()); } // 写锁重入会锁死 if(writeLock.acquire(10,TimeUnit.HOURS)){ System.out.println("Thread Name is :" + Thread.currentThread().getName()); buyPhone(1); }*/ // 写锁 if(writeLock.acquire(10, TimeUnit.HOURS)){ System.out.println("写锁 Thread Name is : " + Thread.currentThread().getName()); buyPhone(1); } // 读锁重入 if(readLock.acquire(10,TimeUnit.HOURS)){ System.out.println("读锁 Thread Name is :" + Thread.currentThread().getName()); System.out.println("phone inventory : " + getPhoneInventory()); } }catch (Exception e){ e.printStackTrace(); }finally{ try{ writeLock.release(); readLock.release(); }catch (Exception e){ e.printStackTrace(); } } }