网站内容布局,集团网站 源码,怎么看网站是否备案,凡科建站怎样建站中站1.lock和synchronized 语法层面
synchronized 是关键字#xff0c;源码在 jvm 中#xff0c;用 c 语言实现#xff1b;
Lock 是接口#xff0c;源码由 jdk 提供#xff0c;用 java 语言实现#xff1b;
使用 synchronized 时#xff0c;退出同步代码块锁会自动释放源码在 jvm 中用 c 语言实现
Lock 是接口源码由 jdk 提供用 java 语言实现
使用 synchronized 时退出同步代码块锁会自动释放而使用 Lock 时需要手动调用 unlock 方法释放锁 功能层面
二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能
Lock 提供了许多 synchronized 不具备的功能例如公平锁、可打断、可超时、多条件变量
Lock 有适合不同场景的实现如 ReentrantLock ReentrantReadWriteLock(读写锁) 性能层面
在没有竞争时synchronized 做了很多优化如偏向锁、轻量级锁性能不赖
在竞争激烈时Lock 的实现通常会提供更好的性能 2.ReentrantLock的代码实现
对于ReentrantLock来说它既可以使用乐观锁思想也可以使用悲观锁思想具体取决于如何使用它的不同方法。 悲观锁思想 在使用ReentrantLock时可以使用它的lock()和unlock()方法来实现悲观锁思想。在使用lock()方法获取锁之前它会一直等待直到获取到锁如果其他线程已经持有锁则当前线程会被阻塞。这种方式与传统的悲观锁思想相似它假设并发访问会导致冲突因此在访问共享资源之前先获取锁。
示例代码
ReentrantLock lock new ReentrantLock();
lock.lock(); // 获取锁
try {// 访问共享资源
} finally {lock.unlock(); // 释放锁
} 乐观锁思想 在使用ReentrantLock时可以使用它的tryLock()方法来实现乐观锁思想。tryLock()方法尝试获取锁如果获取成功则返回true否则返回false不会一直等待。这种方式与乐观锁思想相似它假设并发访问不会导致冲突因此直接进行操作而不获取锁。
示例代码
ReentrantLock lock new ReentrantLock();
if (lock.tryLock()) { // 尝试获取锁try {// 访问共享资源} finally {lock.unlock(); // 释放锁}
} else {// 锁被其他线程持有处理逻辑
}
需要注意的是ReentrantLock的乐观锁思想并不是基于CAS机制实现的而是基于AQSAbstractQueuedSynchronizer实现的。因此它的乐观锁并不是真正意义上的无锁操作而是一种基于线程等待/唤醒机制的乐观策略。 3.ReentrantLock构造原理 ReentrantLock主要利用CASAQS队列来实现。它支持公平锁和非公平锁两者的实现类似
构造方法接受一个可选的公平参数默认非公平锁当设置为true时表示公平锁否则为非公平锁。公平锁的效率往往没有非公平锁的效率高在许多线程访问的情况下公平锁表现出较低的吞吐量。 拓展延申
1)AQS
关键时FIFO双向队列和属性state 是多线程中的队列同步器。是一种锁机制它是做为一个基础框架使用的像ReentrantLock、Semaphore都是基于AQS实现的 AQS内部维护了一个先进先出的双向队列队列中存储的排队的线程 在AQS内部还有一个属性state这个state就相当于是一个资源默认是0无锁状态如果队列中的有一个线程修改成功了state为1则当前线程就相等于获取了资源 在对state修改的时候使用的cas操作保证多个线程修改的情况下原子性 2)了解AQS与Synchronized的区别 3)CAS
CAS的全称是 Compare And Swap(比较再交换)它体现的一种乐观锁的思想在无锁情况下保证线程操作共享数据的原子性。
4)乐观锁与悲观锁
CAS 是基于乐观锁的思想最乐观的估计不怕别的线程来修改共享变量就算改了也没关系我吃亏点再重试呗。
synchronized 是基于悲观锁的思想最悲观的估计得防着其它线程来修改共享变量我上了锁你们都别想改我改完了解开锁你们才有机会。
在Java中synchronized关键字和ReentrantLock类都是悲观锁的实现。
在Java中Atomic类和CASCompare and Swap机制都是乐观锁的实现。 4.Java中synchronized的代码实例
下面是Java中使用synchronized关键字的几种代码示例 同步方法
public synchronized void synchronizedMethod() {// 同步的代码块
} 同步代码块
public void synchronizedBlock() {synchronized (this) {// 同步的代码块}
} 静态同步方法
public static synchronized void synchronizedStaticMethod() {// 同步的代码块
} 同步对象锁
public class MyClass {private final Object lock new Object();
public void synchronizedObjectLock() {synchronized (lock) {// 同步的代码块}}
}
在上述示例中使用synchronized关键字修饰的方法或代码块被称为同步方法或同步代码块它们保证了同一时刻只能有一个线程访问被同步的代码块。synchronized关键字可以修饰方法、代码块、静态方法以及指定的对象锁。
当一个线程进入到一个被synchronized修饰的方法或代码块时它会尝试获取对象的锁。如果锁没有被其他线程占用则该线程获取到锁并执行同步代码块如果锁已经被其他线程占用则该线程会进入阻塞状态直到锁被释放。
需要注意的是synchronized关键字是可重入的即一个线程可以多次获取同一个锁。当一个线程已经获取到锁时它可以再次进入被同步修饰的方法或代码块而不会被阻塞。这种机制可以避免死锁的发生。
另外synchronized关键字还可以用于实现线程之间的通信通过wait()、notify()和notifyAll()方法来实现线程的等待和唤醒操作。这些方法必须在synchronized修饰的代码块中调用并且是针对同一个对象锁的操作。
5.说一下无锁操作
无锁操作是指在并发编程中通过使用特定的算法和数据结构避免使用传统的锁机制如互斥锁、读写锁等从而实现对共享资源的并发访问而无需阻塞或等待其他线程释放锁的操作。
无锁操作通常基于原子操作和CASCompare and Swap机制来实现。CAS是一种乐观锁思想的实现方式它通过比较内存中的值与期望值如果相等则更新为新值否则不做任何操作。CAS操作是原子性的可以保证在多线程环境下的一致性。
无锁操作的优点包括 减少线程的阻塞和切换开销无锁操作不需要等待其他线程释放锁避免了线程的阻塞和切换开销提高了系统的并发性能。 避免死锁和饥饿问题无锁操作不涉及锁的竞争和资源的争夺可以避免死锁和饥饿问题。 提高系统的可伸缩性无锁操作可以实现更细粒度的并发控制提高系统的可伸缩性。
然而无锁操作也存在一些挑战和限制 实现复杂度高无锁操作需要使用特定的算法和数据结构实现起来较为复杂。 适用场景有限无锁操作适用于对共享资源的读操作频繁写操作较少的场景对于复杂的写操作仍然需要使用锁来保证操作的原子性。 ABA问题由于无锁操作不需要获取锁可能会导致ABA问题即一个值被修改为另一个值然后再被修改回原来的值导致线程无法察觉到值的变化。
总之无锁操作是一种高效的并发编程方式可以提高系统的并发性能和可伸缩性但需要根据具体场景和需求来选择合适的并发控制策略。