Chinaunix首页 | 论坛 | 博客
  • 博客访问: 21655
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 132
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-22 00:16
文章分类

全部博文(14)

文章存档

2014年(14)

我的朋友

分类: Java

2014-06-15 22:19:43


在Java多线程编程中,对共享资源进行互斥访问有多种实现方式,如:syncronized,ReentrantLock等。
在此,实现一个使用方式与ReentrantLock相似的自定义锁(注:在实际开发中,直接使用ReentrantLock即可)。

第一版:简单实现。
  1. public class MyLockSimple {
  2.     private boolean flag = false;
  3.    
  4.     public void lock() {
  5.         synchronized (this) {
  6.             while(flag) {
  7.                 try {
  8.                     wait(); // 已经加锁,当前线程需要等待
  9.                 } catch (InterruptedException e) {
  10.                 }
  11.             }
  12.             flag = true;
  13.         }
  14.     }
  15.     
  16.     public void unlock() {
  17.         synchronized (this) {
  18.             flag = false;
  19.             notifyAll(); // 释放锁时通知其他线程
  20.         }
  21.     }
  22. }
仅仅从功能上讲,上述简单版的锁实现是可以的。但是,存在如下2个问题:
1. 如果某个线程连续多次调用lock(),就会自己把自己锁住。
2. 如果某个线程并未执行lock(),而是直接执行unlock(),这样当前线程就可以unlock()其他线程的锁,是不合理的。
为了解决这两个问题,还应该进一步做如下处理:
1. 如果线程已经加锁,则不需要再加锁,避免自己把自己锁住。
2. 如果线程自己并未加锁,则不能释放锁,避免未获得锁的线程释放其他线程的锁。

第二版:改良实现。
  1. public class MyLockGood {
  2.     private int locks = 0;
  3.     private Thread owner = null;

  4.     public void lock() {
  5.         synchronized (this) {
  6.             Thread me = Thread.currentThread();
  7.             while (locks > 0 && me != owner) {// 如果其他线程已经加锁,且不是当前线程自己加的锁,则等待
  8.                 try {
  9.                     wait();
  10.                 } catch (InterruptedException e) {
  11.                 }
  12.             }
  13.             
  14.             // 如果自己已经获得锁,lock数就别增加了
  15.             if(owner == me && locks > 0) {
  16.                 return;
  17.             }
  18.             
  19.             owner = me;
  20.             locks++;
  21.         }
  22.     }

  23.     public void unlock() {
  24.         synchronized (this) {
  25.             Thread me = Thread.currentThread();
  26.             if(locks == 0 || me != owner) {// 没有加锁,或者当前加锁的线程不是自,不需要解锁
  27.                 return;
  28.             }
  29.             
  30.             locks--;
  31.             owner = null;
  32.             notifyAll();
  33.         }
  34.     }
阅读(463) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~