ReentrantLock与synchronized

关于互斥锁:html

所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5以前, 咱们一般使用synchronized机制控制多个线程对共享资源的访问. 而如今, Lock提供了比synchronized机制更普遍的锁定操做, Lock和synchronized机制的主要区别:java

synchronized机制提供了对与每一个对象相关的隐式监视器锁的访问, 并强制全部锁获取和释放均要出如今一个块结构中, 当获取了多个锁时, 它们必须以相反的顺序释放. synchronized机制对锁的释放是隐式的, 只要线程运行的代码超出了synchronized语句块范围, 锁就会被释放. 而Lock机制必须显式的调用Lock对象的unlock()方法才能释放锁, 这为获取锁和释放锁不出如今同一个块结构中, 以及以更自由的顺序释放锁提供了可能. api

 

 

关于可重入: 多线程

1、2.4.1 内部锁线程

Java 提供了原子性的内置锁机制: sychronized 块。它包含两个部分:锁对象的引用和这个锁保护的代码块:htm

synchronized(lock) {对象

// 访问或修改被锁保护的共享状态资源

}get

内部锁扮演了互斥锁( mutual exclusion lock, 也称做 mutex )的角色,一个线程拥有锁的时候,别的线程阻塞等待。同步

 

2.4.2 重进入(Reentrancy )

重入性:指的是同一个线程屡次试图获取它所占有的锁,请求会成功。当释放锁的时候,直到重入次数清零,锁才释放完毕。

Public class Widget {

      Public synchronized void doSomething(){

           …

      }

}

Public class LoggingWidget extends Widget {

   Public synchronized void doSomething(){

      System.out.println(toString()+”:calling doSomething”);

      Super.doSomething();

   }

}

 

2、通常来讲,在多线程程序中,某个任务在持有某对象的锁后才能运行任务,其余任务只有在该任务释放同一对象锁后才能拥有对象锁,而后执行任务。因而,想到,同一个任务在持有同一个对象的锁后,在不释放锁的状况下,继续调用同一个对象的其余同步(synchronized)方法,该任务是否会再次持有该对象锁呢? 

    答案是确定的。同一个任务在调用同一个对象上的其余synchronized方法,能够再次得到该对象锁。 

 

Java代码 

  1. synchronized  m1(){  
  2. //加入此时对锁a的计数是N  
  3.  m2();  //进入m2的方法体以后锁计数是N+1,离开m2后是N  
  4. }  
  5. synchronized m2(){}  

 同一任务和对象锁的问题:http://www.iteye.com/topic/728485

 

 

 

Java代码 

  1. /*public class ReentrantLock  
  2. extends Object implements Lock, Serializable 
  3. */  

  

一个可重入的互斥锁 Lock,它具备与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

 

ReentrantLock 将由最近成功得到锁,而且尚未释放该锁的线程所拥有。当锁没有被另外一个线程所拥有时,调用 lock 的线程将成功获取该锁并返回。若是当前线程已经拥有该锁,此方法将当即返回。可使用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此状况是否发生。

 

此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。不然此锁将没法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的整体吞吐量(即速度很慢,经常极其慢),可是在得到锁和保证锁分配的均衡性时差别较小。不过要注意的是,公平锁不能保证线程调度的公平性。所以,使用公平锁的众多线程中的一员可能得到多倍的成功机会,这种状况发生在其余活动线程没有被处理而且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并无使用公平设置。由于即便其余线程正在等待,只要该锁是可用的,此方法就能够得到成功。

JDK:http://www.xasxt.com/java/api/java/util/concurrent/locks/ReentrantLock.html

相关文章
相关标签/搜索