实现一把不能重入的锁:
package MyLock; public class MyLock { private boolean isLock; public synchronized void lock(){ while (isLock){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } isLock = true; } private synchronized void unlock(){ if(isLock){ isLock = false; notify(); } } static MyLock myLock = new MyLock(); public static void a(){ myLock.lock(); System.out.println("a方法开始"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } b(); myLock.unlock(); } public static void b(){ myLock.lock(); System.out.println("b方法开始"); myLock.unlock(); } public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { a(); } }).start(); } }
a()方法调用b()方法的时候,由于不是一把重入锁,b()方法想获得锁,但是a()方法持有锁却不释放,进入永远的等待。
为了解决线程不可重入的问题,我们再实现一把重入锁,允许获得当前锁的线程无数次进入该锁,记录线程进入锁的次数,当释放锁并且次数为0时,释放该锁。
代码如下:
package MyLock; import java.util.concurrent.atomic.LongAdder; public class My2Lock { private boolean isLock; Thread thread; LongAdder lockCount = new LongAdder(); public synchronized void lock(){ while (isLock && thread!=null && thread!=Thread.currentThread()){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } isLock = true; thread = Thread.currentThread(); lockCount.increment(); } private synchronized void unlock(){ if(thread!=null && thread==Thread.currentThread()){ lockCount.decrement(); if(lockCount.longValue()==0){ thread=null; isLock = false; notify(); } } } static My2Lock myLock = new My2Lock(); public static void a(){ myLock.lock(); System.out.println("a方法开始"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } b(); myLock.unlock(); } public static void b(){ myLock.lock(); System.out.println("b方法开始"); myLock.unlock(); } public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { a(); } }).start(); /*new Thread(new Runnable() { @Override public void run() { b(); } }).start();*/ } }