Java显式锁

synchronized和Lock

synchronized

Java提供的关键字,属于Java语法层面的互斥,隐式锁,由JVM来实现加锁和释放锁。

优点

  • 代码编写简单
  • 可读性好

缺点

  • 加锁和释放锁由JVM来完成,不够灵活。
  • 获取锁的过程不可中断。
  • 不支持超时,获取不到锁会一直阻塞。
  • 非公平锁,不允许修改。
  • 不支持尝试获取锁的判断。
  • 不支持读写锁,比较僵硬。

Lock

Lock属于Java代码级的显式锁,加锁和释放锁由Java代码来完成,和JVM无关。

优点

  • 非常灵活,代码级别的加锁和释放。
  • 获取锁的过程可以被中断。
  • 支持超时,解决无限阻塞。
  • 支持公平锁和非公平锁。
  • 支持尝试获取锁的判断。
  • 支持读写锁。
  • 线程的唤醒更灵活。

缺点

  • 代码编写较复杂。

使用示例

public class SyncLockDemo {
	private int index = 0;
	private Lock lock = new ReentrantLock();
	
	synchronized void syncAdd(){
		System.out.println(++index);
	}
	
	void lockAdd(){
		lock.lock();
		System.out.println(++index);
		lock.unlock();
	}
}

公平锁和非公平锁

公平锁

等待时间最长的线程,优先获取到锁。

优点:锁竞争激烈时,不存在“饥饿”问题。
缺点:性能较差。

锁竞争时,优先分配给等待时间最长的线程,如果该线程处于休眠状态,需要将其唤醒,频繁的挂起和唤醒线程很消耗资源。

非公平锁

优点:效率高。
缺点:锁竞争激烈时,存在“饥饿”问题,可能导致有的线程一直得不到执行。

锁竞争时,优先分配给当前活跃的线程,减少了“公平锁”中对线程频繁的挂起和唤醒,性能更高,但是会导致有些线程一直得不到执行。


两者各有优缺点,需要根据业务场景来选择使用哪种锁。

ReentrantLock默认使用的就是非公平锁!

public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

可重入锁

可重入:线程获得锁之后,能否再次获得锁?

典型应用场景:同步方法的递归、同步方法中调用另一个同步方法。

synchronized和ReentrantLock都支持锁的可重入。

ReentrantLock在内部维护了一个计数器,lock时计数器会加一,unlock时计数器减一,当unlock到0时,才会真正释放锁,其他线程开始竞争。

读写锁

可以查看笔者的博客:《读写锁以及手写实现》

Condition接口

LockSupport

在Java中,挂起和唤醒线程可以使用wait()和notify(),这两个方法来自Object类,调用之前必须前获取到锁的监视器对象,否则会报错。

LockSupport也可以支持将线程挂起和唤醒,直接针对线程,使用起来更加的直观。

API

  • void park()
    阻塞当前线程。

  • void parkNanos(long nanos)
    阻塞当前线程,支持纳秒级的超时。

  • void parkUntil(long deadline)
    阻塞当前线程,直到deadline时间点。

  • void unpark(Thread)
    唤醒指定线程。

使用示例

public class LockSupportDemo {
	public static void main(String[] args) {
		Thread mainThread = Thread.currentThread();

		new Thread(()->{
			//2s后唤醒main
			SleepUtil.SEC.sleep(2);
			LockSupport.unpark(mainThread);
		}).start();

		//main阻塞
		LockSupport.park();

		//唤醒后做的事儿
		System.out.println("main unpack");
	}
}
发布了100 篇原创文章 · 获赞 23 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_32099833/article/details/103217159