3.6.2 如何实现分布式锁

分布式锁可以让多个分布式应用依照先后顺序保持一致性操作,因此在很多方面都有广泛的应用,比如我们在2.1.7计算中的故障处理也谈到2个工头通过竞争一个分布式锁去做任务调度。

LockDemo是利用Fourinone进行分布式锁的实现,设计思路如下:

1)可以启动多个LockDemo实例,每个实例在Fourinone上建立一个自己的node,node的domain为lock,node的值为node(为方便演示,将node的名称和值设为一样)。

2)然后再轮循判断domain lock的第一个元素是否是自己的node,如果是,就执行,这里模拟线程执行8秒,执行完将自己的node删除,代表释放锁;如果不是,就继续等待。

运行步骤如下:

1)启动ParkServerDemo(它的IP端口已经在配置文件指定),结果如图3-11所示:

  1. java -cp fourinone.jar; ParkServerDemo

3.6.2 如何实现分布式锁 - 图1

图3-11 ParkServerDemo

2)运行LockDemo,node名称动态传入参数:

  1. java -cp fourinone.jar; LockDemo ccc
  2. java -cp fourinone.jar; LockDemo bbb
  3. java -cp fourinone.jar; LockDemo aaa

先后启动了多个LockDemo实例,观察它们按照预期的顺序先后获取到锁并进行8秒的业务操作。如图3-12所示。

3.6.2 如何实现分布式锁 - 图2

图3-12 LockDemo

可以看到,由于启动先后顺序为ccc、bbb、aaa,ccc首先获取到锁并开始执行,bbb和aaa处于等待中;ccc处理完成后,bbb获取到锁,开始执行,aaa继续处于等待中;bbb处理完成后,最后aaa开始执行。

下面是demo源码:

  1. // ParkServerDemo
  2. import com.fourinone.BeanContext;
  3. public class ParkServerDemo{
  4. public static void main(String[] args){
  5. BeanContext.startPark();
  6. }
  7. }
  8.  
  9. // LockDemo
  10. import com.fourinone.BeanContext;
  11. import com.fourinone.ParkLocal;
  12. import com.fourinone.ObjectBean;
  13. import java.util.List;
  14.  
  15. public class LockDemo
  16. {
  17. public void lockutil(String node)
  18. {
  19. ParkLocal pl = BeanContext.getPark();
  20. ObjectBean ob = pl.create("lock", node, node);
  21.  
  22. System.out.print("try get lock.");
  23. while(true){
  24. List<ObjectBean> oblist = pl.get("lock");
  25. String curnode = (String)oblist.get(0).toObject();
  26. if(curnode.equals(node)){
  27. System.out.println("");
  28. System.out.println("ok, get lock and doing...");
  29. try{Thread.sleep(8000);}catch(Exception e){}
  30. pl.delete("lock", node);
  31. System.out.println("done.");
  32. break;
  33. }
  34. else
  35. System.out.print(".");
  36. }
  37.  
  38.  
  39. }
  40.  
  41. public static void main(String[] args)
  42. {
  43. LockDemo ld = new LockDemo();
  44. ld.lockutil(args[0]);
  45. }
  46. }