简介
在分布式环境下,为了防止多个服务同时修改同一个值,出现数据同步问题,通常用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(); } }
- 结果
9 8 7 6 5 4 3 2 1 0
- 说明
- 本类开启了十个线程,来操作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(); } }
- 结果
-
9 8 7 6 5 4 3 2 1 0
说明:
- 本类用InterProcessMutex做分布式锁,通过zookeeper节点不能重复的原理来让分布式环境的服务排队处理同一个数据