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所示:
- java -cp fourinone.jar; ParkServerDemo
图3-11 ParkServerDemo
2)运行LockDemo,node名称动态传入参数:
- java -cp fourinone.jar; LockDemo ccc
- java -cp fourinone.jar; LockDemo bbb
- java -cp fourinone.jar; LockDemo aaa
先后启动了多个LockDemo实例,观察它们按照预期的顺序先后获取到锁并进行8秒的业务操作。如图3-12所示。
图3-12 LockDemo
可以看到,由于启动先后顺序为ccc、bbb、aaa,ccc首先获取到锁并开始执行,bbb和aaa处于等待中;ccc处理完成后,bbb获取到锁,开始执行,aaa继续处于等待中;bbb处理完成后,最后aaa开始执行。
下面是demo源码:
- // ParkServerDemo
- import com.fourinone.BeanContext;
- public class ParkServerDemo{
- public static void main(String[] args){
- BeanContext.startPark();
- }
- }
- // LockDemo
- import com.fourinone.BeanContext;
- import com.fourinone.ParkLocal;
- import com.fourinone.ObjectBean;
- import java.util.List;
- public class LockDemo
- {
- public void lockutil(String node)
- {
- ParkLocal pl = BeanContext.getPark();
- ObjectBean ob = pl.create("lock", node, node);
- System.out.print("try get lock.");
- while(true){
- List<ObjectBean> oblist = pl.get("lock");
- String curnode = (String)oblist.get(0).toObject();
- if(curnode.equals(node)){
- System.out.println("");
- System.out.println("ok, get lock and doing...");
- try{Thread.sleep(8000);}catch(Exception e){}
- pl.delete("lock", node);
- System.out.println("done.");
- break;
- }
- else
- System.out.print(".");
- }
- }
- public static void main(String[] args)
- {
- LockDemo ld = new LockDemo();
- ld.lockutil(args[0]);
- }
- }