【245、乐观锁和悲观锁】

35 阅读2分钟

乐观锁和悲观锁是并发控制机制中的两种不同的思路。

  1. 悲观锁

悲观锁的思想是认为并发情况下多个线程之间会产生冲突,因此在访问共享资源时,需要先获取锁,确保同一时刻只有一个线程可以访问该资源。如果其他线程也需要访问该资源,则必须等待当前线程释放锁后才能进行访问。 悲观锁的实现方式主要有以下两种:

  • 互斥锁:使用互斥锁可以保证共享资源的独占性,即同一时刻只能有一个线程访问共享资源。当一个线程需要访问共享资源时,它会请求锁。如果锁已经被其他线程占用,则线程会被阻塞,直到锁被释放为止。
  • 读写锁:读写锁分为读锁和写锁两种。读锁可以被多个线程同时获取,但写锁只能被一个线程获取。当一个线程需要访问共享资源时,如果只需要读取资源,则可以获取读锁;如果需要修改资源,则必须先获取写锁。当写锁被获取时,其他线程的读锁和写锁都会被阻塞。

悲观锁使用的机制包括:synchronized关键字和ReentrantLock等。

  1. 乐观锁

乐观锁的思想是认为在大部分情况下,多个线程之间不会产生冲突,因此在访问共享资源时,不需要获取锁,可以直接进行访问。如果在执行过程中发现有冲突,则进行重试或者放弃操作。

  • 版本号机制:在共享资源中添加一个版本号字段,每次修改资源时都会将版本号加1。当一个线程需要访问共享资源时,先获取当前的版本号,然后进行操作。如果操作过程中发现版本号被其他线程修改了,则说明发生了冲突,需要进行重试。
  • CAS(Compare and Swap)机制:CAS是一种原子性的操作,它能够在没有使用锁的情况下实现并发控制。CAS操作包括三个参数:要修改的内存地址、原来的值和新值。如果原来的值与内存中的值相同,则将内存中的值修改为新值,否则不进行任何操作。

总的来说,悲观锁在访问共享资源时会加锁,保证同一时刻只有一个线程访问共享资源,而乐观锁则是在访问共享资源时不加锁,通过版本号等机制来避免冲突,提高并发效率。但是乐观锁的实现需要在程序中增加一些额外的逻辑,如版本号的维护和冲突的处理等,对程序的开发和维护都会带来一定的复杂度。