最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java使用zookeeper實現(xiàn)的分布式鎖示例

 更新時間:2014年05月07日 09:59:11   作者:  
這篇文章主要介紹了java使用zookeeper實現(xiàn)的分布式鎖示例,需要的朋友可以參考下

使用zookeeper實現(xiàn)的分布式鎖

分布式鎖,實現(xiàn)了Lock接口

復制代碼 代碼如下:

package com.concurrent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

/**
   DistributedLock lock = null;
 try {
  lock = new DistributedLock("127.0.0.1:2182","test");
  lock.lock();
  //do something...
 } catch (Exception e) {
  e.printStackTrace();
 }
 finally {
  if(lock != null)
   lock.unlock();
 }
 * @author xueliang
 *
 */
public class DistributedLock implements Lock, Watcher{
 private ZooKeeper zk;
 private String root = "/locks";//根
 private String lockName;//競爭資源的標志
 private String waitNode;//等待前一個鎖
 private String myZnode;//當前鎖
 private CountDownLatch latch;//計數(shù)器
 private int sessionTimeout = 30000;
 private List<Exception> exception = new ArrayList<Exception>();

 /**
  * 創(chuàng)建分布式鎖,使用前請確認config配置的zookeeper服務可用
  * @param config 127.0.0.1:2181
  * @param lockName 競爭資源標志,lockName中不能包含單詞lock
  */
 public DistributedLock(String config, String lockName){
  this.lockName = lockName;
  // 創(chuàng)建一個與服務器的連接
   try {
   zk = new ZooKeeper(config, sessionTimeout, this);
   Stat stat = zk.exists(root, false);
   if(stat == null){
    // 創(chuàng)建根節(jié)點
    zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
   }
  } catch (IOException e) {
   exception.add(e);
  } catch (KeeperException e) {
   exception.add(e);
  } catch (InterruptedException e) {
   exception.add(e);
  }
 }

 /**
  * zookeeper節(jié)點的監(jiān)視器
  */
 public void process(WatchedEvent event) {
  if(this.latch != null) { 
            this.latch.countDown(); 
        }
 }

 public void lock() {
  if(exception.size() > 0){
   throw new LockException(exception.get(0));
  }
  try {
   if(this.tryLock()){
    System.out.println("Thread " + Thread.currentThread().getId() + " " +myZnode + " get lock true");
    return;
   }
   else{
    waitForLock(waitNode, sessionTimeout);//等待鎖
   }
  } catch (KeeperException e) {
   throw new LockException(e);
  } catch (InterruptedException e) {
   throw new LockException(e);
  }
 }

 public boolean tryLock() {
  try {
   String splitStr = "_lock_";
   if(lockName.contains(splitStr))
    throw new LockException("lockName can not contains \\u000B");
   //創(chuàng)建臨時子節(jié)點
   myZnode = zk.create(root + "/" + lockName + splitStr, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
   System.out.println(myZnode + " is created ");
   //取出所有子節(jié)點
   List<String> subNodes = zk.getChildren(root, false);
   //取出所有l(wèi)ockName的鎖
   List<String> lockObjNodes = new ArrayList<String>();
   for (String node : subNodes) {
    String _node = node.split(splitStr)[0];
    if(_node.equals(lockName)){
     lockObjNodes.add(node);
    }
   }
   Collections.sort(lockObjNodes);
   System.out.println(myZnode + "==" + lockObjNodes.get(0));
   if(myZnode.equals(root+"/"+lockObjNodes.get(0))){
    //如果是最小的節(jié)點,則表示取得鎖
             return true;
         }
   //如果不是最小的節(jié)點,找到比自己小1的節(jié)點
   String subMyZnode = myZnode.substring(myZnode.lastIndexOf("/") + 1);
   waitNode = lockObjNodes.get(Collections.binarySearch(lockObjNodes, subMyZnode) - 1);
  } catch (KeeperException e) {
   throw new LockException(e);
  } catch (InterruptedException e) {
   throw new LockException(e);
  }
  return false;
 }

 public boolean tryLock(long time, TimeUnit unit) {
  try {
   if(this.tryLock()){
    return true;
   }
         return waitForLock(waitNode,time);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return false;
 }

 private boolean waitForLock(String lower, long waitTime) throws InterruptedException, KeeperException {
        Stat stat = zk.exists(root + "/" + lower,true);
        //判斷比自己小一個數(shù)的節(jié)點是否存在,如果不存在則無需等待鎖,同時注冊監(jiān)聽
        if(stat != null){
         System.out.println("Thread " + Thread.currentThread().getId() + " waiting for " + root + "/" + lower);
         this.latch = new CountDownLatch(1);
         this.latch.await(waitTime, TimeUnit.MILLISECONDS);
         this.latch = null;
        }
        return true;
    }

 public void unlock() {
  try {
   System.out.println("unlock " + myZnode);
   zk.delete(myZnode,-1);
   myZnode = null;
   zk.close();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (KeeperException e) {
   e.printStackTrace();
  }
 }

 public void lockInterruptibly() throws InterruptedException {
  this.lock();
 }

 public Condition newCondition() {
  return null;
 }

 public class LockException extends RuntimeException {
  private static final long serialVersionUID = 1L;
  public LockException(String e){
   super(e);
  }
  public LockException(Exception e){
   super(e);
  }
 }

}

并發(fā)測試工具

復制代碼 代碼如下:

package com.concurrent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
  ConcurrentTask[] task = new ConcurrentTask[5];
  for(int i=0;i<task.length;i++){
      task[i] = new ConcurrentTask(){
    public void run() {
     System.out.println("==============");

    }};
  }
  new ConcurrentTest(task);
 * @author xueliang
 *
 */
public class ConcurrentTest {
 private CountDownLatch startSignal = new CountDownLatch(1);//開始閥門
 private CountDownLatch doneSignal = null;//結(jié)束閥門
 private CopyOnWriteArrayList<Long> list = new CopyOnWriteArrayList<Long>();
 private AtomicInteger err = new AtomicInteger();//原子遞增
 private ConcurrentTask[] task = null;

 public ConcurrentTest(ConcurrentTask... task){
  this.task = task;
  if(task == null){
   System.out.println("task can not null");
   System.exit(1);
  }
  doneSignal = new CountDownLatch(task.length);
  start();
 }
 /**
  * @param args
  * @throws ClassNotFoundException
  */
 private void start(){
  //創(chuàng)建線程,并將所有線程等待在閥門處
  createThread();
  //打開閥門
  startSignal.countDown();//遞減鎖存器的計數(shù),如果計數(shù)到達零,則釋放所有等待的線程
  try {
   doneSignal.await();//等待所有線程都執(zhí)行完畢
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  //計算執(zhí)行時間
  getExeTime();
 }
 /**
  * 初始化所有線程,并在閥門處等待
  */
 private void createThread() {
  long len = doneSignal.getCount();
  for (int i = 0; i < len; i++) {
   final int j = i;
   new Thread(new Runnable(){
    public void run() {
     try {
      startSignal.await();//使當前線程在鎖存器倒計數(shù)至零之前一直等待
      long start = System.currentTimeMillis();
      task[j].run();
      long end = (System.currentTimeMillis() - start);
      list.add(end);
     } catch (Exception e) {
      err.getAndIncrement();//相當于err++
     }
     doneSignal.countDown();
    }
   }).start();
  }
 }
 /**
  * 計算平均響應時間
  */
 private void getExeTime() {
  int size = list.size();
  List<Long> _list = new ArrayList<Long>(size);
  _list.addAll(list);
  Collections.sort(_list);
  long min = _list.get(0);
  long max = _list.get(size-1);
  long sum = 0L;
  for (Long t : _list) {
   sum += t;
  }
  long avg = sum/size;
  System.out.println("min: " + min);
  System.out.println("max: " + max);
  System.out.println("avg: " + avg);
  System.out.println("err: " + err.get());
 }

 public interface ConcurrentTask {
  void run();
 }

}

測試

復制代碼 代碼如下:

package com.concurrent;

import com.concurrent.ConcurrentTest.ConcurrentTask;

public class ZkTest {
 public static void main(String[] args) {
  Runnable task1 = new Runnable(){
   public void run() {
    DistributedLock lock = null;
    try {
     lock = new DistributedLock("127.0.0.1:2182","test1");
     //lock = new DistributedLock("127.0.0.1:2182","test2");
     lock.lock();
     Thread.sleep(3000);
     System.out.println("===Thread " + Thread.currentThread().getId() + " running");
    } catch (Exception e) {
     e.printStackTrace();
    }
    finally {
     if(lock != null)
      lock.unlock();
    }

   }

  };
  new Thread(task1).start();
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e1) {
   e1.printStackTrace();
  }
  ConcurrentTask[] tasks = new ConcurrentTask[60];
  for(int i=0;i<tasks.length;i++){
   ConcurrentTask task3 = new ConcurrentTask(){
    public void run() {
     DistributedLock lock = null;
     try {
      lock = new DistributedLock("127.0.0.1:2183","test2");
      lock.lock();
      System.out.println("Thread " + Thread.currentThread().getId() + " running");
     } catch (Exception e) {
      e.printStackTrace();
     }
     finally {
      lock.unlock();
     }

    }
   };
   tasks[i] = task3;
  }
  new ConcurrentTest(tasks);
 }
}

相關(guān)文章

  • Spring Data JPA使用JPQL與原生SQL進行查詢的操作

    Spring Data JPA使用JPQL與原生SQL進行查詢的操作

    這篇文章主要介紹了Spring Data JPA使用JPQL與原生SQL進行查詢的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java報錯sun.misc.Unsafe.park(Native Method)問題

    Java報錯sun.misc.Unsafe.park(Native Method)問題

    這篇文章主要介紹了Java報錯sun.misc.Unsafe.park(Native Method)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • java調(diào)用相互依賴的dll的處理方法

    java調(diào)用相互依賴的dll的處理方法

    大家好,本篇文章主要講的是java調(diào)用相互依賴的dll的處理方法,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • java8新特性之stream流中reduce()求和知識總結(jié)

    java8新特性之stream流中reduce()求和知識總結(jié)

    今天帶大家回顧Java8的新特性,文中對stream流中reduce()求和的相關(guān)知識作了詳細的介紹,對正在學習java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • java實現(xiàn)單源最短路徑

    java實現(xiàn)單源最短路徑

    這篇文章主要為大家詳細介紹了java實現(xiàn)單源最短路徑,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringBoot整合Redis之編寫RedisConfig

    SpringBoot整合Redis之編寫RedisConfig

    RedisConfig需要對redis提供的兩個Template的序列化配置,所以本文為大家詳細介紹了SpringBoot整合Redis如何編寫RedisConfig,需要的可以參考下
    2022-06-06
  • Spring線程池ThreadPoolTaskExecutor配置詳情

    Spring線程池ThreadPoolTaskExecutor配置詳情

    本篇文章主要介紹了Spring線程池ThreadPoolTaskExecutor配置詳情,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • SpringBoot中@ConditionalOnProperty注解的使用方法詳解

    SpringBoot中@ConditionalOnProperty注解的使用方法詳解

    這篇文章主要介紹了SpringBoot中@ConditionalOnProperty注解的使用方法詳解,在開發(fā)基于SpringBoot框架的項目時,會用到下面的條件注解,有時會有需要控制配置類是否生效或注入到Spring上下文中的場景,可以使用@ConditionalOnProperty注解來控制,需要的朋友可以參考下
    2024-01-01
  • Java使用雙異步實現(xiàn)將Excel的數(shù)據(jù)導入數(shù)據(jù)庫

    Java使用雙異步實現(xiàn)將Excel的數(shù)據(jù)導入數(shù)據(jù)庫

    在開發(fā)中,我們經(jīng)常會遇到這樣的需求,將Excel的數(shù)據(jù)導入數(shù)據(jù)庫中,這篇文章主要來和大家講講Java如何使用雙異步實現(xiàn)將Excel的數(shù)據(jù)導入數(shù)據(jù)庫,感興趣的可以了解下
    2024-01-01
  • 優(yōu)化spring?boot應用后6s內(nèi)啟動內(nèi)存減半

    優(yōu)化spring?boot應用后6s內(nèi)啟動內(nèi)存減半

    這篇文章主要為大家介紹了優(yōu)化spring?boot后應用6s內(nèi)啟動內(nèi)存減半的優(yōu)化示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-02-02

最新評論

出国| 南宫市| 内丘县| 南昌县| 白水县| 鞍山市| 南皮县| 措勤县| 大田县| 湖州市| 双柏县| 汤原县| 天门市| 郑州市| 田东县| 桂阳县| 武宁县| 扎鲁特旗| 安仁县| 原阳县| 枣阳市| 衡水市| 南充市| 舟山市| 手机| 潢川县| 射阳县| 贵定县| 宿州市| 塔城市| 玉林市| 丰顺县| 安国市| 吴江市| 恩平市| 南皮县| 新巴尔虎右旗| 青岛市| 祁连县| 荥阳市| 潢川县|