curator框架对zookeeper分布式的锁全局同步的实现

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.study</groupId>
	<artifactId>curator</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>curator</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-client</artifactId>
			<version>2.11.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>2.11.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>2.11.0</version>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.9.2</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
	</dependencies>
</project>

package com.study.curator;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
//分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁
public class TestCuratorLock {
	public static void main(String[] args) throws InterruptedException {
		//CountDownLatch一种同步帮助,允许一个或多个线程等待直到一组正在执行的操作线程完成。
		//在线程可以通过等待之前,必须调用的时间倒计时的次数 
		CountDownLatch latch = new CountDownLatch(5);
		String zookeeperConnectionString = "hadoop:2181,hadoop1:2182,hadoop2:2182";
		//重新链接策略的抽象;1000毫秒重试间隔,3次重试
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
		//使用newClient方式创建Zookeeper Client
		CuratorFramework client = CuratorFrameworkFactory.newClient(
				zookeeperConnectionString, retryPolicy);
		client.start();
		System.out.println("客户端启动。。。。");
		//执行器,提供管理多个异步Task运行的方法和终止,生成一个Future来跟踪Task
		ExecutorService exec = Executors.newCachedThreadPool();
		for (int i = 0; i < 5; i++) {
			//提交一个runnable任务,执行并返回一个Future,Future描述任务结果
			//如果任务成功完成,Future的get方法返回null
			exec.submit(new MyLock("client" + i, client, latch));
		}
		exec.shutdown();
		//导致当前线程等待直到锁存器已计数到零,除非线程被中断
		latch.await();
		System.out.println("所有任务执行完毕");
		client.close();
		System.out.println("客户端关闭。。。。");
	}

	static class MyLock implements Runnable {
		private String name;
		private CuratorFramework client;
		private CountDownLatch latch;

		public MyLock(String name, CuratorFramework client, CountDownLatch latch) {
			this.name = name;
			this.client = client;
			this.latch = latch;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public void run() {
			//InterProcessMutex:全局可重入的锁(Shared Reentrant Lock)的实现;
			//Shared意味着锁是全局可见的, 客户端都可以请求锁
			//Reentrant和JDK的ReentrantLock类似,意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞。
			InterProcessMutex lock = new InterProcessMutex(client,
					"/test_group");
			try {
				//通过acquire获得锁,并提供超时机制:
				if (lock.acquire(120, TimeUnit.SECONDS)) {
					try {
						System.out.println("----------" + this.name
								+ "获得资源----------");
						System.out.println("----------" + this.name
								+ "正在处理资源----------");
						Thread.sleep(10 * 1000);
						System.out.println("----------" + this.name
								+ "资源使用完毕----------");
						latch.countDown();
					} finally {
						//通过release()方法释放锁。
						//InterProcessMutex 实例可以重用。
						lock.release();
						System.out.println("----------" + this.name
								+ "释放----------");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

执行同时进入zkCli命令行,查看.一下是部分内容

[zk: localhost:2181(CONNECTED) 5] ls /test_group
[_c_3b8229b5-d116-4588-befd-3eed639cce4f-lock-0000000003, _c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 6] ls /test_group
[_c_3b8229b5-d116-4588-befd-3eed639cce4f-lock-0000000003, _c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 7] ls /test_group
[_c_7d5b30d7-73ef-4739-9686-bb008fa4b7f7-lock-0000000004]
[zk: localhost:2181(CONNECTED) 8] ls /test_group
[]

eclipse控制台输出如下:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
客户端启动。。。。
----------client3获得资源----------
----------client3正在处理资源----------
----------client3资源使用完毕----------
----------client3释放----------
----------client1获得资源----------
----------client1正在处理资源----------
----------client1资源使用完毕----------
----------client1释放----------
----------client4获得资源----------
----------client4正在处理资源----------
----------client4资源使用完毕----------
----------client4释放----------
----------client2获得资源----------
----------client2正在处理资源----------
----------client2资源使用完毕----------
----------client2释放----------
----------client0获得资源----------
----------client0正在处理资源----------
----------client0资源使用完毕----------
所有任务执行完毕
----------client0释放----------
客户端关闭。。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值