天天看点

最简单分布式锁ZK实现方案

分布式锁简单封装

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

<code>package</code> <code>com.hellojd.cloud.locks.v1;</code>

<code>import</code> <code>org.apache.zookeeper.*;</code>

<code>import</code> <code>java.io.IOException;</code>

<code>import</code> <code>java.util.concurrent.CountDownLatch;</code>

<code>import</code> <code>static</code> <code>org.apache.zookeeper.Watcher.Event.KeeperState.SyncConnected;</code>

<code>/**</code>

<code> </code><code>* 最简单分布式锁实现方案</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>ZookerSession </code><code>implements</code> <code>Watcher {</code>

<code>    </code><code>private</code> <code>CountDownLatch countDownLatch=</code><code>new</code> <code>CountDownLatch(</code><code>1</code><code>);</code>

<code>    </code><code>private</code> <code>ZooKeeper zooKeeper;</code>

<code>    </code><code>private</code> <code>static</code>  <code>class</code>  <code>Singleton{</code>

<code>        </code><code>private</code>  <code>static</code>  <code>ZookerSession instance;</code>

<code>        </code><code>static</code> <code>{</code>

<code>            </code><code>instance = </code><code>new</code> <code>ZookerSession();</code>

<code>        </code><code>}</code>

<code>        </code><code>public</code> <code>static</code> <code>ZookerSession getInstance(){</code>

<code>            </code><code>return</code> <code>instance;</code>

<code>    </code><code>}</code>

<code>    </code><code>public</code> <code>static</code> <code>ZookerSession getInstance(){</code>

<code>        </code><code>return</code> <code>Singleton.getInstance();</code>

<code>    </code><code>public</code> <code>ZookerSession() {</code>

<code>        </code><code>try</code> <code>{</code>

<code>            </code><code>this</code><code>.zooKeeper = </code><code>new</code> <code>ZooKeeper(</code><code>"192.168.0.10:2181"</code><code>,</code><code>50000</code><code>,</code><code>this</code><code>);</code>

<code>            </code><code>countDownLatch.await();</code>

<code>            </code><code>System.out.println(</code><code>"state:  "</code><code>+zooKeeper.getState());</code>

<code>            </code><code>System.out.println(</code><code>"connection estalished!!"</code><code>);</code>

<code>        </code><code>} </code><code>catch</code> <code>(IOException e) {</code>

<code>            </code><code>e.printStackTrace();</code>

<code>        </code><code>} </code><code>catch</code> <code>(InterruptedException e) {</code>

<code>    </code><code>public</code> <code>ZooKeeper getZooKeeper(){</code><code>return</code> <code>this</code><code>.zooKeeper;}</code>

<code>    </code><code>@Override</code>

<code>    </code><code>public</code> <code>void</code> <code>process(WatchedEvent event) {</code>

<code>        </code><code>if</code><code>(event.getState()==SyncConnected){</code>

<code>            </code><code>countDownLatch.countDown();</code>

<code>    </code><code>public</code> <code>void</code> <code>releaseDistributeLock(Long id){</code>

<code>        </code><code>String path =</code><code>"/lock_"</code><code>+id;</code>

<code>            </code><code>zooKeeper.delete(path,-</code><code>1</code><code>);</code>

<code>        </code><code>} </code><code>catch</code> <code>(KeeperException e) {</code>

<code>    </code><code>public</code> <code>void</code> <code>acquireDistributeLock(Long id){</code>

<code>            </code><code>zooKeeper.create(path,</code><code>null</code><code>, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);</code>

<code>//            System.out.println("success to acquire lock "+id);</code>

<code>            </code><code>//没有获取到锁</code>

<code>            </code><code>int</code> <code>count=</code><code>0</code><code>;</code>

<code>            </code><code>while</code> <code>(</code><code>true</code><code>){</code>

<code>                </code><code>try</code><code>{</code>

<code>                    </code><code>Thread.sleep(</code><code>200</code><code>);</code>

<code>                    </code><code>zooKeeper.create(path,</code><code>null</code><code>, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);</code>

<code>                </code><code>}</code><code>catch</code> <code>(InterruptedException e1) {</code>

<code>                    </code><code>count++;</code>

<code>                    </code><code>continue</code><code>;</code>

<code>                </code><code>} </code><code>catch</code> <code>(KeeperException e1) {</code>

<code>//                    e1.printStackTrace();</code>

<code>                </code><code>}</code>

<code>//                System.out.println("success to acquire lock "+id);</code>

<code>                </code><code>break</code><code>;</code>

<code>            </code><code>}</code>

<code>}</code>

2.测试线程

<code>import</code> <code>org.apache.zookeeper.CreateMode;</code>

<code>import</code> <code>org.apache.zookeeper.KeeperException;</code>

<code>import</code> <code>org.apache.zookeeper.ZooDefs;</code>

<code>import</code> <code>org.apache.zookeeper.data.Stat;</code>

<code> </code><code>* 测试线程</code>

<code>public</code> <code>class</code> <code>Task </code><code>implements</code>  <code>Runnable {</code>

<code>    </code><code>private</code> <code>int</code> <code>loop;</code>

<code>    </code><code>private</code> <code>Long lockid;</code>

<code>    </code><code>ZookerSession zs;</code>

<code>    </code><code>public</code> <code>Task(</code><code>int</code> <code>loop,Long lockid) {</code>

<code>        </code><code>zs = ZookerSession.getInstance();</code>

<code>        </code><code>this</code><code>.loop = loop;</code>

<code>        </code><code>this</code><code>.lockid = lockid;</code>

<code>    </code><code>public</code> <code>void</code> <code>run() {</code>

<code>        </code><code>ZookerSession.getInstance().acquireDistributeLock(lockid);</code>

<code>        </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i&lt;loop;i++){</code>

<code>            </code><code>int</code> <code>count = getcount();</code>

<code>            </code><code>System.out.println(Thread.currentThread().getName()+</code><code>"--&gt;"</code><code>+count);</code>

<code>            </code><code>count(++count);</code>

<code>        </code><code>zs.releaseDistributeLock(lockid);</code>

<code>    </code><code>//计数</code>

<code>    </code><code>public</code> <code>void</code> <code>count(</code><code>int</code> <code>count){</code>

<code>            </code><code>Stat s = zs.getZooKeeper().exists(</code><code>"/count"</code><code>, </code><code>false</code><code>);</code>

<code>            </code><code>if</code><code>(s==</code><code>null</code><code>){</code>

<code>                </code><code>System.out.println(</code><code>"count 不存在"</code><code>);</code>

<code>                </code><code>zs.getZooKeeper().create(</code><code>"/count"</code><code>,String.valueOf(count).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);</code>

<code>            </code><code>}</code><code>else</code><code>{</code>

<code>                </code><code>zs.getZooKeeper().setData(</code><code>"/count"</code><code>,String.valueOf(count).getBytes(),-</code><code>1</code><code>);</code>

<code>    </code><code>public</code> <code>int</code> <code>getcount(){</code>

<code>                </code><code>zs.getZooKeeper().create(</code><code>"/count"</code><code>,String.valueOf(</code><code>0</code><code>).getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);</code>

<code>                </code><code>return</code> <code>0</code><code>;</code>

<code>                </code><code>byte</code><code>[] data = zs.getZooKeeper().getData(</code><code>"/count"</code><code>, </code><code>false</code><code>, </code><code>null</code><code>);</code>

<code>                </code><code>return</code> <code>Integer.valueOf(</code><code>new</code> <code>String(data));</code>

<code>        </code><code>return</code> <code>-</code><code>1</code><code>;</code>

<code>    </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>

<code>        </code><code>long</code> <code>LOCKID = 2l;</code>

<code>        </code><code>for</code><code>(</code><code>int</code> <code>i=</code><code>0</code><code>;i&lt;</code><code>100</code><code>;i++){</code>

<code>            </code><code>new</code> <code>Thread(</code><code>new</code> <code>Task(</code><code>1</code><code>, LOCKID)).start();</code>

原理:分布式锁通过死循环+实现等待效果。如果线程可以创建节点,则成功获取锁;

释放锁:就是将数据节点在ZK上删除。

缺点:简单且性能低。有风险。如果获取锁的线程中断,导致任务异常。

本文转自 randy_shandong 51CTO博客,原文链接:http://blog.51cto.com/dba10g/1975120,如需转载请自行联系原作者