![](/attachment/201406/15/24262685_1402841189wl6w.jpg)
在Java多线程编程中,对共享资源进行互斥访问有多种实现方式,如:syncronized,ReentrantLock等。
在此,实现一个使用方式与ReentrantLock相似的自定义锁(
注:在实际开发中,直接使用ReentrantLock即可)。
第一版:简单实现。
-
public class MyLockSimple {
-
private boolean flag = false;
-
-
public void lock() {
-
synchronized (this) {
-
while(flag) {
-
try {
-
wait(); // 已经加锁,当前线程需要等待
-
} catch (InterruptedException e) {
-
}
-
}
-
flag = true;
-
}
-
}
-
-
public void unlock() {
-
synchronized (this) {
-
flag = false;
-
notifyAll(); // 释放锁时通知其他线程
-
}
-
}
-
}
仅仅从功能上讲,上述简单版的锁实现是可以的。但是,存在如下2个问题:
1. 如果某个线程连续多次调用lock(),就会自己把自己锁住。
2. 如果某个线程并未执行lock(),而是直接执行unlock(),这样当前线程就可以unlock()其他线程的锁,是不合理的。
为了解决这两个问题,还应该进一步做如下处理:
1. 如果线程已经加锁,则不需要再加锁,避免自己把自己锁住。
2. 如果线程自己并未加锁,则不能释放锁,避免未获得锁的线程释放其他线程的锁。
第二版:改良实现。
-
public class MyLockGood {
-
private int locks = 0;
-
private Thread owner = null;
-
-
public void lock() {
-
synchronized (this) {
-
Thread me = Thread.currentThread();
-
while (locks > 0 && me != owner) {// 如果其他线程已经加锁,且不是当前线程自己加的锁,则等待
-
try {
-
wait();
-
} catch (InterruptedException e) {
-
}
-
}
-
-
// 如果自己已经获得锁,lock数就别增加了
-
if(owner == me && locks > 0) {
-
return;
-
}
-
-
owner = me;
-
locks++;
-
}
-
}
-
-
public void unlock() {
-
synchronized (this) {
-
Thread me = Thread.currentThread();
-
if(locks == 0 || me != owner) {// 没有加锁,或者当前加锁的线程不是自己,不需要解锁
-
return;
-
}
-
-
locks--;
-
owner = null;
-
notifyAll();
-
}
-
}
阅读(463) | 评论(0) | 转发(0) |