实现成员变量 基于线程安全的依次递减功能:
ReentrantLock:
package zklock;
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
利用Curator的Zookeeper分布式锁:
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.jd.test</groupId>
<artifactId>JavaTest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
<!--
虽然ZooKeeper开发团队仍然将ZooKeeper 3.5.x视为“测试版”,但实际情况是它被许多用户用于生产。
但是,ZooKeeper 3.4.x也用于生产。在Apache Curator 4.0之前,
两个版本的Apache Curator都支持两个版本的ZooKeeper。
从Curator 4.0开始,通过相同的Curator库支持两个版本的ZooKeeper。
Curator 4.0在软兼容模式下支持ZooKeeper 3.4.x集合。要使用此模式,
必须在将Curator添加到依赖关系管理工具时排除ZooKeeper。
-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
</project>
package zklock;
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 = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
/** 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
可以看到 一样的保证了线程安全,且基于分布式的模式。