首页 > 编程语言 > 详细

Java锁概念基础

时间:2015-07-19 13:08:12      阅读:211      评论:0      收藏:0      [点我收藏+]

  Java中的锁不管是Lock还是synchronized都可以分为互斥锁和非互斥锁。

 

  互斥锁只能被一个线程持有,其他线程只能等待锁的释放。synchronized,ReentrantLock,ReadWriteReentrantLock的WriteLock是互斥的,但ReadLock不是互斥的。

  FileLock可以设置为互斥锁或者非互斥锁。

 

  实现锁时可以基于操作系统的调度,也可以以自旋的形式来实现。

  利用操作系统的指令,让线程等待,当锁可用时,让线程醒过来。这种适合需要等待长时间的。如果等待的时间短,这个操作的代价是较大的。

  用循环不断的轮询锁的状态,锁可用的时候就退出。这就是自旋锁。这样里面基本不做什么事情的循环是非常耗CPU的,如果等待锁的时间很长,用这种方式是不合适的。

 

  自旋锁是JVM实现的,下面的例子可以简单的描述自旋锁

public class MyWaitNotify3{

  MonitorObject myMonitorObject = new MonitorObject();
  boolean wasSignalled = false;

  public void doWait(){
    synchronized(myMonitorObject){
      while(!wasSignalled){
        try{
                         
   }
catch(InterruptedException e){...} } //clear signal and continue running.   ...
wasSignalled = false; } } public void doNotify(){ synchronized(myMonitorObject){ wasSignalled = true; myMonitorObject.notify(); } } }

  没有其他的线程调用doNotify之前,doWait将一直自旋,等待wasSignalled变为true。

 

  自旋锁的缺点:

  1.自旋锁一直占用CPU,他在未获得锁的情况下,一直运行自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。

  2.在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁。

 

  可以使用-XX:+UseSpinning来打开自旋锁,使用-XX:PreBlockSpin来设置等自旋待的次数。

 

  有些时候我们会在完全没必要的情况下用到了锁,可以使用逃逸分析和锁消除来提升系统的性能。

  例如,下面的局部变量StringBuffer完全用不到加锁,反而会影响性能。 

public String createNewString(String a,String b){
    StringBuffer sb = new StringBuffer();
    return  sb.append(a).append(b);
}

  逃逸分析和锁消除可以使用-XX:+DoEscapeAnalysis和-XX:+EliminateLocks。锁消除需要JVM工作在server模式下。

 

  可重入锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。ReentrantLock 和synchronized 都是可重入锁。  

public class Test implements Runnable{

    public synchronized void get(){
        System.out.println(Thread.currentThread().getId());
        set();
    }

    public synchronized void set(){
        System.out.println(Thread.currentThread().getId());
    }

    @Override
    public void run() {
        get();
    }
    public static void main(String[] args) {
        Test ss=new Test();
        new Thread(ss).start();
        new Thread(ss).start();
        new Thread(ss).start();
    }
}

 

 

 

  

  

Java锁概念基础

原文:http://www.cnblogs.com/lnlvinso/p/4658429.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!