> 文章列表 > Java锁的区别:独占模式与共享模式

Java锁的区别:独占模式与共享模式

Java锁的区别:独占模式与共享模式

目录

前言:

Java 独占模式的锁有哪些?

共享模式的锁有哪些?

Java即是 独占模式又是共享模式的锁有哪些?


前言:

资源有两种共享模式,或者说两种同步⽅式:

  1. 独占模式(Exclusive):资源是独占的,⼀次只能⼀个线程获取。如ReentrantLock。
  2. 共享模式(Share):同时可以被多个线程获取,具体的资源个数可以通过参数指定。如Semaphore/CountDownLatch。

⼀般情况下,⼦类只需要根据需求实现其中⼀种模式,当然也有同时实现两种模式的同步类,如 ReadWriteLock

Java 独占模式的锁有哪些?

在Java中,独占模式的锁(Exclusive Mode Lock)通常也被称为互斥锁(Mutex Lock),主要是用于实现线程之间的互斥同步,防止多个线程同时访问共享资源而导致的数据竞争和不一致性问题。下面是Java中独占模式的锁的一些常见实现:

  1. synchronized关键字:synchronized关键字是Java中最基本的互斥锁实现,它可以用来修饰方法和代码块,实现线程之间的互斥同步。在Java 5之前,synchronized锁是基于操作系统提供的内置锁机制实现的,因此也被称为重量级锁(Heavyweight Lock)。在Java 6及以后的版本中,synchronized锁也进行了一系列的优化,引入了偏向锁、轻量级锁和重量级锁等概念,从而提高了锁的性能和效率。

  2. ReentrantLock类:ReentrantLock是Java 5引入的一个可重入锁实现,它也是一个独占锁。与synchronized锁相比,ReentrantLock锁提供了更多的高级特性,如可中断锁、超时锁、公平锁和非公平锁等。另外,ReentrantLock锁还支持Condition条件对象,可以实现更复杂的线程同步。

  3. StampedLock类:StampedLock是Java 8引入的一个乐观锁实现,它通过使用读写锁的特性来提供高性能的读写操作,同时也支持像ReentrantLock那样的独占锁。StampedLock锁的主要特点是,当读操作的冲突率较低时,它可以比读写锁提供更高的并发性能,但在高并发情况下,写操作的性能可能会变得较差。

需要注意的是,以上锁的实现都是独占模式的锁,也就是同一时间只有一个线程可以持有锁。在实际应用中,需要根据具体的场景选择合适的锁来实现线程之间的同步和互斥。

共享模式的锁有哪些?

在Java中,共享模式的锁(Shared Mode Lock)主要用于实现多个线程之间的并发访问,允许多个线程同时访问同一个共享资源,以提高系统的并发性和吞吐量。下面是Java中共享模式的锁的一些常见实现:

  1. CountDownLatch类:CountDownLatch是Java 5引入的一个倒计时锁实现,它可以让一个或多个线程等待一个或多个事件的发生。CountDownLatch锁的主要特点是,在计数器减到0之前,所有线程都必须等待,而且一旦计数器变为0,所有等待的线程都可以同时执行。CountDownLatch锁适用于一个线程等待其他多个线程完成某些操作的情况,如多个线程同时执行某个任务,等待所有线程执行完成后再进行下一步操作。

  2. CyclicBarrier类:CyclicBarrier是Java 5引入的一个栅栏锁实现,它可以让一组线程在某个点上进行同步等待,并且只有当所有线程都到达该点时才能继续执行。与CountDownLatch不同的是,CyclicBarrier锁可以重复使用,即在所有线程到达栅栏之后,它会自动重置计数器,并且可以继续使用。CyclicBarrier锁适用于一组线程需要在某个点上进行同步等待的情况,如多个线程同时执行某个任务,等待所有线程执行完成后再进行下一步操作。

  3. Semaphore类:Semaphore是Java 5引入的一个信号量实现,它可以控制对共享资源的访问权限。Semaphore锁的主要特点是,它可以指定一个访问共享资源的最大线程数,当已经达到最大线程数时,其他线程必须等待。与CountDownLatch和CyclicBarrier不同的是,Semaphore锁不是一次性的,而是可以重复使用,即每次释放锁之后,其他线程可以继续获取锁。Semaphore锁适用于一组线程需要有限制地访问共享资源的情况,如数据库连接池等。

需要注意的是,在实际应用中,共享模式的锁的选择要根据具体的场景来决定,同时需要注意锁的实现和使用方式,避免出现死锁和性能问题。

Java即是 独占模式又是共享模式的锁有哪些?

在Java中,有一些锁既可以作为独占模式的锁,也可以作为共享模式的锁。这些锁主要包括以下几种:

  1. ReentrantReadWriteLock:ReentrantReadWriteLock是一个可重入的读写锁,它支持读锁的共享模式和写锁的独占模式。在读锁的共享模式下,多个线程可以同时获取读锁,并且读锁之间不会互斥,从而提高了系统的并发性和吞吐量;而在写锁的独占模式下,只有一个线程可以获取写锁,其他线程必须等待。ReentrantReadWriteLock锁适用于读多写少的场景,如缓存等。

  2. Semaphore:Semaphore是一个信号量,它可以控制对共享资源的访问权限。Semaphore既可以作为独占模式的锁,也可以作为共享模式的锁使用。在独占模式下,Semaphore的计数器为1,只有一个线程可以获取信号量;而在共享模式下,Semaphore的计数器可以设置为大于1的值,多个线程可以同时获取信号量,并且信号量之间不会互斥,从而提高了系统的并发性和吞吐量。Semaphore锁适用于一组线程需要有限制地访问共享资源的场景。

需要注意的是,虽然这些锁可以同时作为独占模式的锁和共享模式的锁使用,但在实际应用中,需要根据具体的场景来决定使用哪种模式,并注意锁的实现和使用方式,避免出现死锁和性能问题。