Java中的锁详解说明
下文笔者讲述java中锁的详解,如下所示:
可保证在同一时间只有一个线程可运行return ++count
下文将使用Lock代替synchronized达到了同样的目的
运行unlock()会重新将isLocked设置为false
并且通知(唤醒)其中一个(若有的话)在lock()方法中调用了wait()函数而处于等待状态的线程。
这意味着如果一个java线程进入了代码中的synchronized同步块
并因此获得了该同步块使用的同步对象对应的管程上的锁
那么这个线程可以进入由同一个管程对象所同步的另一个java代码块
当同一个线程重复对一个锁对象加锁的次数
当unlock时,则减少锁定的次数,直到锁次数为零时,则解锁
java锁简介
锁与synchronized同步块具有同样的功能:是一种线程同步机制 但锁比Java中的synchronized同步块更复杂 ------------------------------------------------------------------------------------------ 因为锁是由synchronized同步块的方式实现的
一个简单的锁简介说明
public class Counter{ private int count = 0; public int inc(){ synchronized(this){ return ++count; } } }以上的代码中使用了synchronized(this)代码块
可保证在同一时间只有一个线程可运行return ++count
下文将使用Lock代替synchronized达到了同样的目的
public class Counter{ private Lock lock = new Lock(); private int count = 0; public int inc(){ lock.lock(); int newCount = ++count; lock.unlock(); return newCount; } } lock()方法会对Lock实例对象进行加锁 因此所有对该对象调用lock()方法的线程都会被阻塞 直到该Lock对象的unlock()方法被调用Lock类的实现
public class Counter{ public class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } } --------代码中的 while(isLocked)循环,称之为“自旋锁” 当isLocked为true时,调用lock()的线程在wait()调用上阻塞等待 为防止该线程没有收到notify()调用也从wait()中返回(也称作虚假唤醒), 这个线程会重新去检查isLocked条件以决定当前是否可以安全地继续执行还是需要重新保持等待, 而不是认为线程被唤醒了就可以安全地继续执行了 当isLocked为false,当前线程会退出while(isLocked)循环,并将isLocked设回true,让其它正在调用lock()方法的线程能够在Lock实例上加锁当线程运行完毕临界区(lock()和unlock()之间)的代码后,会调用unlock()
运行unlock()会重新将isLocked设置为false
并且通知(唤醒)其中一个(若有的话)在lock()方法中调用了wait()函数而处于等待状态的线程。
锁的可重入性
Java中的synchronized同步块是可重入的这意味着如果一个java线程进入了代码中的synchronized同步块
并因此获得了该同步块使用的同步对象对应的管程上的锁
那么这个线程可以进入由同一个管程对象所同步的另一个java代码块
public class Reentrant{ public synchronized fun1(){ fun2(); } public synchronized fun2(){ // } } 此处的fun1()和fun2()都被声明为synchronized, Java中和synchronized(this)块等效 当一个线程调用了fun1() 在fun1()里调用fun2()就没有什么问题 因为这两个方法(代码块)都由同一个管程对象("this")所同步下面的代码为不可重入锁
public class Reentrant2{ Lock lock = new Lock(); public outer(){ lock.lock(); inner(); lock.unlock(); } public synchronized inner(){ lock.lock(); //业务代码 lock.unlock(); } } /* 运行outer()的线程首先会锁住Lock实例,当继续调用inner()。inner()方法中该线程将再一次尝试锁住Lock实例,此时该操作会失败(也就是说该线程会被阻塞), 因为这个Lock实例已经在outer()方法中被锁住了 由于两次lock()之间没有调用unlock(),第二次调用lock就会阻塞 */ /*Lock类可重入性的调整示例分享*/ public class Lock{ boolean isLocked = false; Thread lockedBy = null; int lockedCount = 0; public synchronized void lock() throws InterruptedException{ Thread callingThread =Thread.currentThread(); while(isLocked && lockedBy != callingThread){ wait(); } isLocked = true; lockedCount++; lockedBy = callingThread; } public synchronized void unlock(){ if(Thread.curentThread() == this.lockedBy){ lockedCount--; if(lockedCount == 0){ isLocked = false; notify(); } } } }以上代码中的while循环(自旋锁)已经考虑到已锁住该Lock实例的线程
当同一个线程重复对一个锁对象加锁的次数
当unlock时,则减少锁定的次数,直到锁次数为零时,则解锁
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。