标签:
分布式锁在分布式应用当中是要经常用到的,主要是解决分布式资源访问冲突的问题。 一开始考虑采用ReentrantLock来实现,但是实际上去实现的时候,是有问题的,ReentrantLock的lock和unlock要求必须是在同一线程进行,而分布式应用中,lock和unlock是两次不相关的请求,因此肯定不是同一线程,因此导致无法使用ReentrantLock。public synchronized void lock(){
while(lock){
Thread.sleep(1);
}
lock=true;
...
}
public synchronized void unlock(){
lock=false;
...
}public interface DistributedLock extends RemoteObject {
long lock() throws RemoteException, TimeoutException;
long tryLock(long time, TimeUnit unit) throws RemoteException, TimeoutException;
void unlock(long token) throws RemoteException;
}public class DistributedLockImpl extends UnicastRemoteObject implements DistributedLock {
/**
* 超时单位
*/
private TimeUnit lockTimeoutUnit = TimeUnit.SECONDS;
/**
* 锁的令牌
*/
private volatile long token = 0;
/**
* 同步对象
*/
byte[] lock = new byte[0];
/**
* 默认永不超时
*/
long lockTimeout = 60 * 60;//默认超时3600秒
long beginLockTime;//获取令牌时间,单位毫秒
public DistributedLockImpl() throws RemoteException {
super();
}
/**
* @param lockTimeout 锁超时时间,如果加锁的对象不解锁,超时之后自动解锁
* @param lockTimeoutUnit
* @throws RemoteException
*/
public DistributedLockImpl(long lockTimeout, TimeUnit lockTimeoutUnit) throws RemoteException {
super();
this.lockTimeout = lockTimeout;
this.lockTimeoutUnit = this.lockTimeoutUnit;
}
public long lock() throws TimeoutException {
return tryLock(0, TimeUnit.MILLISECONDS);
}
private boolean isLockTimeout() {
if (lockTimeout <= 0) {
return false;
}
return (System.currentTimeMillis() - beginLockTime) < lockTimeoutUnit.toMillis(lockTimeout);
}
private long getToken() {
beginLockTime = System.currentTimeMillis();
token = System.nanoTime();
return token;
}
public long tryLock(long time, TimeUnit unit) throws TimeoutException {
synchronized (lock) {
long startTime = System.nanoTime();
while (token != 0 && isLockTimeout()) {
try {
if (time > 0) {
long endTime = System.nanoTime();
if (endTime - startTime >= unit.toMillis(time)) {
throw new TimeoutException();
}
}
Thread.sleep(1);
} catch (InterruptedException e) {
//DO Noting
}
}
return getToken();
}
}
public void unlock(long token) {
if (this.token != 0 && token == this.token) {
this.token = 0;
} else {
throw new RuntimeException("令牌" + token + "无效.");
}
}
}public class TestDLock {
public static void main(String[] args) throws Exception {
RmiServer rmiServer = new LocalRmiServer();
DistributedLockImpl distributedLock = new DistributedLockImpl();
rmiServer.registerRemoteObject("lock1", distributedLock);
MultiThreadProcessor processor = new MultiThreadProcessor("aa");
for (int i = 0; i < 8; i++) {
processor.addProcessor(new RunLock("aa" + i));
}
long s = System.currentTimeMillis();
processor.start();
long e = System.currentTimeMillis();
System.out.println(e - s);
rmiServer.unexportObject(distributedLock);
}
}
class RunLock extends AbstractProcessor {
public RunLock(String name) {
super(name);
}
@Override
protected void action() throws Exception {
try {
RmiServer client = new RemoteRmiServer();
DistributedLock lock = client.getRemoteObject("lock1");
for (int i = 0; i < 1000; i++) {
long token = lock.lock();
lock.unlock(token);
}
System.out.println("end-" + Thread.currentThread().getId());
} catch (RemoteException e) {
e.printStackTrace();
}
}
}| 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 | -0 [main] INFO - 线程组<aa>运行开始,线程数8... -3 [aa-aa0] INFO - 线程<aa-aa0>运行开始... -3 [aa-aa1] INFO - 线程<aa-aa1>运行开始... -3 [aa-aa2] INFO - 线程<aa-aa2>运行开始... -3 [aa-aa3] INFO - 线程<aa-aa3>运行开始... -3 [aa-aa4] INFO - 线程<aa-aa4>运行开始... -4 [aa-aa5] INFO - 线程<aa-aa5>运行开始... -4 [aa-aa6] INFO - 线程<aa-aa6>运行开始... -8 [aa-aa7] INFO - 线程<aa-aa7>运行开始... end-19 -9050 [aa-aa3] INFO - 线程<aa-aa3>运行结束 end-17 -9052 [aa-aa1] INFO - 线程<aa-aa1>运行结束 end-20 -9056 [aa-aa4] INFO - 线程<aa-aa4>运行结束 end-16 -9058 [aa-aa0] INFO - 线程<aa-aa0>运行结束 end-21 -9059 [aa-aa5] INFO - 线程<aa-aa5>运行结束 end-26 -9063 [aa-aa7] INFO - 线程<aa-aa7>运行结束 end-18 -9064 [aa-aa2] INFO - 线程<aa-aa2>运行结束 end-22 -9065 [aa-aa6] INFO - 线程<aa-aa6>运行结束 -9066 [main] INFO - 线程组<aa>运行结束, 用时:9065ms 9069 |
欢迎关注:http://web.j2ee.top。本例涉及的代码和框架资料,将会在这里分享。《自己动手写框架》QQ群:228977971,让我们一起成长!
标签:
原文地址:http://blog.csdn.net/cndes/article/details/46368633