排它锁(Exclusive Locks,简称X锁),又称为写锁。
如果事务T1对数据对象o1加上了排它锁,那么在整个加锁期间,只允许事务T1对o1进行读取和更新操作,其他任何事务都不能在这个数据对象进行任何类型的操作(不能再对该对象加锁),直至T1释放了排他锁。
public class DistributeLock implements Watcher{ private ZooKeeper zooKeeper; /** zookeeper服务器地址 */ public static final String connectString = "192.168.50.110:2181,192.168.50.111:2181,192.168.50.112:2181"; /** 定义session失效时间 */ public static final int sessionTimeout = 5000; private String path = "/lock"; private CountDownLatch cl; private CountDownLatch cl2 = new CountDownLatch(1); Thread t; public DistributeLock(String host ,final String path) { try { this.zooKeeper = new ZooKeeper(host, 6000,this); try { cl2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } this.path = path; } /** * 加锁 */ public void lock() { try { zooKeeper.create(path, path.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); } catch (Exception e) { try { cl= new CountDownLatch(1); cl.await(1000,TimeUnit.MICROSECONDS); } catch (InterruptedException e1) { e1.printStackTrace(); } lock(); } } /** * 释放锁 */ public void unlock() { try { zooKeeper.exists(path, true); zooKeeper.delete(path, -1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } @Override public void process(WatchedEvent event) { System.out.println("进入 process 。。。。。event = " + event); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } if (event == null) { return; } // 连接状态 KeeperState keeperState = event.getState(); // 事件类型 EventType eventType = event.getType(); // 受影响的path String path = event.getPath(); String logPrefix=""; System.out.println(logPrefix + "收到Watcher通知"); System.out.println(logPrefix + "连接状态:\t" + keeperState.toString()); System.out.println(logPrefix + "事件类型:\t" + eventType.toString()); if (KeeperState.SyncConnected == keeperState) { // 成功连接上ZK服务器 if (EventType.None == eventType) { System.out.println( "成功连接上ZK服务器"); cl2.countDown(); } //删除节点 else if (EventType.NodeDeleted == eventType) { System.out.println("线程:"+t.getName()+logPrefix + "节点 " + path + " 被删除"); } else ; } else if (KeeperState.Disconnected == keeperState) { System.out.println(logPrefix + "与ZK服务器断开连接"); } else if (KeeperState.AuthFailed == keeperState) { System.out.println(logPrefix + "权限检查失败"); } else if (KeeperState.Expired == keeperState) { System.out.println(logPrefix + "会话失效"); } else ; System.out.println("--------------------------------------------"); } }
测试类(不加锁):
public class LockTest implements Runnable { static int i = 0; DistributeLock lock = new DistributeLock(ZookeeperUtil.connectString, "/lock"); @Override public void run() { // lock.lock(); for (int j = 0; j < 1000000; j++) { i++; } // lock.unlock(); } public static void main(String[] args) throws InterruptedException { LockTest lockTest2 = new LockTest(); LockTest lockTest1 = new LockTest(); Thread thread = new Thread(lockTest2); Thread thread2 = new Thread(lockTest1); thread.start(); thread2.start(); thread.join(); thread2.join(); System.out.println(i); }
测试结果:
测试类(加锁):
public class LockTest implements Runnable { static int i = 0; DistributeLock lock = new DistributeLock(ZookeeperUtil.connectString, "/lock"); @Override public void run() { lock.lock(); for (int j = 0; j < 1000000; j++) { i++; } lock.unlock(); } public static void main(String[] args) throws InterruptedException { LockTest lockTest2 = new LockTest(); LockTest lockTest1 = new LockTest(); Thread thread = new Thread(lockTest2); Thread thread2 = new Thread(lockTest1); thread.start(); thread2.start(); thread.join(); thread2.join(); System.out.println(i); } }
测试结果: