简介
在分布式环境下,为了防止多个服务同时修改同一个值,出现数据同步问题,通常用redis和zookeeper做分布式锁,在这里我们用zookeeper做分布式锁,并和单点环境中ReenTranLock锁相比较
1、ReenTranLock
package bjsxt.curator.lock;import java.util.concurrent.CountDownLatch;import java.util.concurrent.locks.ReentrantLock;public class Lock1 { static ReentrantLock reentrantLock = new ReentrantLock(); static int count = 10; public static void genarNo(){ try { reentrantLock.lock(); count--; System.out.println(count); } finally { reentrantLock.unlock(); } } public static void main(String[] args) throws Exception{ final CountDownLatch countdown = new CountDownLatch(1); for(int i = 0; i < 10; i++){ new Thread(new Runnable() { @Override public void run() { try { countdown.await(); genarNo(); } catch (Exception e) { e.printStackTrace(); } finally { } } },"t" + i).start(); } Thread.sleep(50); countdown.countDown(); }}
- 结果
9876543210
- 说明
- 本类开启了十个线程,来操作count值,从结果可以看出是线程安全的
2、zookeeper分布锁InterProcessMutex
package bjsxt.curator.lock;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.CountDownLatch;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 Lock2 { /** zookeeper地址 */ static final String CONNECT_ADDR = "192.168.0.4:2181,192.168.0.9:2181,192.168.0.6:2181"; /** session超时时间 */ static final int SESSION_OUTTIME = 5000; static int count = 10; public static void genarNo(){ try { count--; System.out.println(count); } finally { } } public static void main(String[] args) throws Exception { //1 重试策略:初试时间为1s 重试10次 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 10); //2 通过工厂创建连接 CuratorFramework cf = CuratorFrameworkFactory.builder() .connectString(CONNECT_ADDR) .sessionTimeoutMs(SESSION_OUTTIME) .retryPolicy(retryPolicy)// .namespace("super") .build(); //3 开启连接 cf.start(); //4 分布式锁 final InterProcessMutex lock = new InterProcessMutex(cf, "/super"); final CountDownLatch countdown = new CountDownLatch(1); for(int i = 0; i < 10; i++){ new Thread(new Runnable() { @Override public void run() { try { countdown.await(); //加锁 lock.acquire(); //-------------业务处理开始 genarNo(); //-------------业务处理结束 } catch (Exception e) { e.printStackTrace(); } finally { try { //释放 lock.release(); } catch (Exception e) { e.printStackTrace(); } } } },"t" + i).start(); } Thread.sleep(100); countdown.countDown(); }}
- 结果
-
9876543210
说明:
- 本类用InterProcessMutex做分布式锁,通过zookeeper节点不能重复的原理来让分布式环境的服务排队处理同一个数据