Java Lock Mechanism

Java Lock Mechanism

 

1. Java Lock Mechanism

 

Before Java 5.0, synchronized是唯一的选择,Java5.0concurrent包提供了新的Lock机制。

 

Condition Object 监视器方法(waitnotify notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

 

 

2. 对象的锁

 

所有对象都自动含有单一的锁。

JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同线程在此对象上获得锁时,计数会递增。

 

只有首先获得锁的线程才能继续获取该对象上的多个锁。

 

每当线程离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的线程就可以使用此资源。

 

3. synchronized

 

因为synchronized锁是加在对象上的, 所以下面的代码是等效的。

 

public  class ThreadSafe {

        public synchronized void  method1 () {

                //access the resource protected by this lock

        }

}

 

 

public  class ThreadSafe {

        public void method1 () {

                synchronized (this) {

                        //access the resource protected by this lock

            }

        }

}

 

 

4. synchronized and Lock

 

4.1 同步到单一对象

 

public  class ThreadSafe {

        public void method1 () {

                synchronized (this) {

                        //access the resource protected by this lock

            }

        }

        public void method2 () {

                synchronized (this) {

                        //access the resource protected by this lock

            }

        }

}

 

由于同步在同一的对象上(this),所以method1method2是互斥的。

 

采用Lock也能实现同样的效果:

 

public  class ThreadSafe {

        private Lock lock = new ReentrantLock();

 

        public void method1 () {

                lock.lock();

try{

                         //access the resource protected by this lock

}

finally {

          lock.unlock();

      }

        }

 

        public void method2 () {

                lock.lock();

try{

                         //access the resource protected by this lock

}

finally {

          lock.unlock();

      }

        }

}

由于同步在同一个lock对象上,所以method1method2是互斥的。

 

4.2 同步到多个对象

 

public  class ThreadSafe {

   private Object lock1 = new Object();

   private Object lock2 = new Object();

 

        public void method1 () {

                synchronized (lock1) {

                        //access the resource protected by this lock

            }

        }

        public void method2 () {

                synchronized (lock2) {

                        //access the resource protected by this lock

            }

        }

}

 

由于同步不同的对象lock1lock2上,所以method1method2不是互斥的。

 

采用Lock也能实现同样的效果:

 

public  class ThreadSafe {

        private Lock lock1 = new ReentrantLock();

        private Lock lock2 = new ReentrantLock();

 

        public void method1 () {

                lock1.lock();

try{

                         //access the resource protected by this lock

}

finally {

          lock1.unlock();

      }

        }

 

        public void method2 () {

                lock2.lock();

try{

                         //access the resource protected by this lock

}

finally {

          lock2.unlock();

      }

        }

}

由于同步不同的对象lock1lock2上,所以method1method2不是互斥的。

 

5. NbiLocalQueue

 

    public void send(NbiMessage message) throws NbiException {

        try {

            msgReceiverLock.lock();

            nbiQueue.add(message);

            msgReceiverLock.signal();

        } finally {

            msgReceiverLock.unlock();

        }

    }

msgReceiverLock封装了一个ReentrantLock,所以基本上来说,这个实现和synchronized方式实现没有本质的区别。

当然Java5.0提供的Lock机制也有自身的一些优势,请参考下面的章节和JDK的帮助文档。

 

 

6. Condition Object监视器方法

 

6.1 Object监视器方法实现

 

class ObjectBoundedBuffer {
   final private Object lock = new Object();
 
   final Object[] items = new Object[100];
   int putptr, takeptr, count;
 
   public void put(Object x){
     synchronized (lock) {
         while (count == items.length)
             lock.wait();
         items[putptr] = x; 
         if (++putptr == items.length) putptr = 0;
         ++count;
           
         lock.notify();
     }
   }
 
   public Object take() {
 
     synchronized (lock){
         while (count == 0 )
             lock.wait();
          Object x = items[takeptr]; 
          if (++takeptr == items.length) takeptr = 0;
          --count;
           
          lock.notify();
          return x;
     }
   }
}

 

 

6.2 Condition实现

 

class ConditionBoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 
 
   final Object[] items = new Object[100];
   int putptr, takeptr, count;
 
   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }
 
   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0) 
         notEmpty.await();
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   } 
 }

 

 

7. Lock的优势

 

据说Locksynchronized有更好的性能优势。

 

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

 

Lock 接口的实现允许锁定在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁定。

Lock 实现提供了使用 synchronized 方法和语句所没有的其他功能,包括提供了一个非块结构的获取锁定尝试 (tryLock())、一个获取可中断锁定的尝试 (lockInterruptibly()) 和一个获取超时失效锁定的尝试 (tryLock(long, TimeUnit))

Lock 类还可以提供与隐式监视器锁定完全不同的行为和语义,如保证排序、非重入用法或死锁检测。如果某个实现提供了这样特殊的语义,则该实现必须对这些语义加以记录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值