【锁】作为并发共享数据保证一致性的工具,显然这个工具的地位是非常重要的,这里把这个锁的原理以及实现手动打造出来,为以后对锁的理解打下更好的基础,以后学习juc的锁会容易许多。
以前使用的【锁】可以理解为内置锁,也就是系统提供好的,内置锁的特点是【可重入】,举个简单的例子:你去朋友家里,进到朋友家的客厅了,你就有权利进到他家的卫生间,进到他家的厨房等,这个就叫做可重入。
所以在我们的多线程里面,当某一个线程试图获取一个已经由它自己持有的锁的时候,那么这个请求会立刻成功,我们每一个锁都有计数器,再次进入以后将这个锁再加1,当退出来了这个计数器会减一个1,直到这个计数器等于0的时候,锁释放。如果没有可重入锁的支持,在第二次企图获得锁的时候可能就会进入死锁状态。可重入锁在后期随处可见。
多线程_高级主题_可重入锁_原理实现

内置锁都支持可重入。

package com.sxt.others;
/**
 * 可重入锁: 锁可以延续使用
 * 
 * @author 
 *
 */
public class LockTest01 {
	public void test() {
	//  第一次获得锁
        synchronized(this) {
            while(true) {
                //  第二次获得同样的锁
                synchronized(this) {
                    System.out.println("ReentrantLock!");
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
	}
	public static void main(String[] args) {
		new LockTest01().test();
	}
}



package com.sxt.others;
/**
 * 不可重入锁: 锁不可以延续使用
 * 
 * @author 
 *
 */
public class LockTest02 {
	Lock lock = new Lock();
	public void a() throws InterruptedException {
		lock.lock();
		doSomething();
		lock.unlock();
	}
	//不可重入
	public void doSomething() throws InterruptedException {
		lock.lock();
		//...................
		lock.unlock();
	}
	public static void main(String[] args) throws InterruptedException {
		LockTest02 test = new LockTest02();
		test.a();
		test.doSomething();
	}

}
// 不可重入锁
class Lock{
	//是否占用
	private boolean isLocked = false;
	//使用锁
	public synchronized void lock() throws InterruptedException {
		while(isLocked) {
			wait();
		}
		
		isLocked = true;
	}
	//释放锁
	public synchronized void unlock() {
		isLocked = false;
		notify();
		
	}
}



package com.sxt.others;
/**
 * 可重入锁: 锁可以延续使用 + 计数器
 * 
 * @author 
 *
 */
public class LockTest03 {
	ReLock lock = new ReLock();
	public void a() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		doSomething();
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}
	//不可重入
	public void doSomething() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		//...................
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}
	public static void main(String[] args) throws InterruptedException {
		LockTest03 test = new LockTest03();
		test.a();			
		Thread.sleep(1000);		
		System.out.println(test.lock.getHoldCount());
	}

}
// 可重入锁
class ReLock{
	//是否占用
	private boolean isLocked = false;
	private Thread lockedBy = null; //存储线程
	private int holdCount = 0;
	//使用锁
	public synchronized void lock() throws InterruptedException {
		Thread t = Thread.currentThread();
		while(isLocked && lockedBy != t) {
			wait();
		}
		
		isLocked = true;
		lockedBy = t;
		holdCount ++;
	}
	//释放锁
	public synchronized void unlock() {
		if(Thread.currentThread() == lockedBy) {
			holdCount --;
			if(holdCount ==0) {
				isLocked = false;
				notify();
				lockedBy = null;
			}		
		}		
	}
	public int getHoldCount() {
		return holdCount;
	}
}



package com.sxt.others;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 可重入锁: 锁可以延续使用 + 计数器
 * ReentrantLock
 * @author 
 *
 */
public class LockTest04 {
	ReentrantLock lock = new ReentrantLock();
	public void a() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		doSomething();
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}
	//不可重入
	public void doSomething() throws InterruptedException {
		lock.lock();
		System.out.println(lock.getHoldCount());
		//...................
		lock.unlock();
		System.out.println(lock.getHoldCount());
	}
	public static void main(String[] args) throws InterruptedException {
		LockTest04 test = new LockTest04();
		test.a();			
		Thread.sleep(1000);		
		System.out.println(test.lock.getHoldCount());
	}

}

相关文章:

  • 2021-12-27
  • 2021-06-20
  • 2021-12-06
  • 2021-10-09
  • 2021-08-14
  • 2022-12-23
  • 2021-08-09
猜你喜欢
  • 2022-12-23
  • 2021-09-26
  • 2021-05-07
  • 2022-12-23
  • 2021-04-09
  • 2022-01-05
相关资源
相似解决方案