java中锁比synchronized更具有灵活性,其底层原理简单说就是,集合了AbstractQueuedSynchronizer同步器。同步器作为上层的锁(或同步组件)和底层同步状态控制技术之间的桥梁,主要采用了同步队列、同步状态、CAS原子操作方法,实现了同步状态管理、线程排队、等待与唤醒等底层操作。同步器与锁隔离了现实者和使用者的关注点。
模型:
class exampleLock implements Lock {
private final Sync = new Sync(); //同步器Sync
public exampleLock(int state) {
setState(state); //设置锁状态
}
@Override
public void lock() {
//调用同步器Sync获取锁逻辑
}
@Override
public void unlock {
//调用同步器Sync释放锁逻辑
}
//其他锁操作方法(略)
static final class Sync extends AbstractQueuedSynchronizer {
@Override
public int tryAcquire(int arg) {
//锁状态操作逻辑
return int变量;
}
@Override
public boolean tryRelease(int arg) {
//锁状态操作逻辑
return boolean变量;
}
//其他底层操作方法(略)
}
}
实例
TwinsLock
TwinsLock确保该锁同时仅能被两个线程占有。
package lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class TwinsLock implements Lock {
private final Sync sync = new Sync(2);
private static final class Sync extends AbstractQueuedSynchronizer {
public Sync(int count) {
if (count <= 0) {
throw new IllegalArgumentException("count must large than zero");
}
setState(count);
}
@Override
protected int tryAcquireShared(int arg) {
for (; ; ) {
int current = getState();
int newCount = current - arg;
if (newCount < 0 || compareAndSetState(current, newCount)) {
return newCount;
}
}
}
@Override
protected boolean tryReleaseShared(int arg) {
for (; ;) {
int current = getState();
int newCount = current + arg;
if (compareAndSetState(current, newCount)) {
return true;
}
}
}
}
@Override
public void lock() {
sync.acquireShared(1);
}
@Override
public void unlock() {
sync.releaseShared(1);
}
/******以下省略******/
@Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub
}
@Override
public boolean tryLock() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
// TODO Auto-generated method stub
return false;
}
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
}
}
测试
package lock;
import org.junit.Test;
public class TwinsLockTest {
@Test
public void test() {
final TwinsLock lock = new TwinsLock();
class Worker extends Thread {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + " looped in while.");
lock.lock();
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " got lock.");
Thread.sleep(100);
} catch (InterruptedException ex) {
} finally {
lock.unlock();
}
}
}
}
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
Worker worker = new Worker();
threads[i] = new Thread(worker, "worker-" + i);
}
for (int i = 0; i < 10; i++) {
threads[i].start();
}
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(100);
System.out.println();
} catch (InterruptedException e) {
}
}
}
}
测试结果
结果如下。线程名称成对出现,说明同时仅有两个线程持有锁
worker-0 looped in while.
worker-1 looped in while.
worker-2 looped in while.
worker-3 looped in while.
worker-4 looped in while.
worker-5 looped in while.
worker-6 looped in while.
worker-7 looped in while.
worker-8 looped in while.
worker-9 looped in while.
worker-0 got lock.
worker-1 got lock.
worker-0 looped in while.
worker-1 looped in while.
worker-0 got lock.
worker-2 got lock.
worker-0 looped in while.
worker-2 looped in while.
worker-4 got lock.
worker-3 got lock.
worker-4 looped in while.
worker-3 looped in while.
worker-6 got lock.
worker-5 got lock.
worker-6 looped in while.
worker-5 looped in while.
worker-7 got lock.
worker-8 got lock.
worker-7 looped in while.
worker-8 looped in while.
worker-1 got lock.
worker-9 got lock.
worker-1 looped in while.
worker-9 looped in while.
worker-2 got lock.
worker-0 got lock.
worker-2 looped in while.
worker-0 looped in while.
worker-4 got lock.
worker-3 got lock.
worker-4 looped in while.
worker-3 looped in while.
worker-6 got lock.
worker-5 got lock.
worker-6 looped in while.
worker-5 looped in while.
worker-7 got lock.
worker-8 got lock.
worker-7 looped in while.
worker-8 looped in while.