`

Concurrent - 锁

    博客分类:
  • Lock
 
阅读更多

原创转载请注明出处:http://agilestyle.iteye.com/blog/2356898

 

什么是可重入锁(ReentrantLock)?


Java多线程中可以使用synchronized关键字来实现线程之间的同步互斥,但在JDK1.5中新增加了ReentrantLock类也能达到同样的效果,并且在扩展功能上也更加强大,比如 嗅探锁定、多路分支通知等功能

ReentrantLock并不是替代synchronized的方法,而是当synchronized不适用时,作为一种可选的高级功能;

从代码上尽量用synchronized,jvm会对synchronized做一定的优化,并且代码可维护和稳定。只有在需要ReentrantLock的一些特性时,可以考虑用ReentrantLock实现。

 

当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其它方法?

可进入非synchronized方法

 

synchronized和java.util.concurrent.locks.Lock的异同?

  • synchronized相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在它一个对象身上;synchronized无法中断一个正在等待获得锁的线程,也即多线程竞争一个锁时,其余未得到锁的线程只能不停的尝试获得锁,而不能中断。这种情况对于大量的竞争线程会造成性能的下降等后果。
  • Lock对象可以创建多个Condition(即对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性地进行通知,在调度线程上更加灵活。

所以在synchronized无法满足需求的情况下,Lock可以作为一种高级工具,这些功能包括“可定时的、可轮询的与可中断的锁获取操作,公平队列,以及非块结构的锁”否则还是优先使用synchronized 

 

乐观锁和悲观锁的理解及如何实现,有哪些实现方式?

乐观锁 —— CAS

悲观锁 —— mutex

Note:

数据库方面

乐观锁 —— version字段

悲观锁 —— for update

 

如何实现乐观锁(CAS)?如何避免ABA问题?

ABA问题。因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。

 

ABA问题的解决思路就是使用版本号。在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A - 2B-3A。

 

从Java1.5开始JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。

http://ifeve.com/atomic-operation/

 

读写锁可以用于什么应用场景?

http://ifeve.com/read-write-locks/

 

什么时候应该使用可重入锁?

若一个程序或子程序可以“安全的被并行执行(Parallel computing)”,则称其为可重入(reentrant或re-entrant)的。即当该子程序正在运行时,可以再次进入并执行它(并行执行时,个别的执行结果,都符合设计时的预期)。可重入概念是在单线程操作系统的时代提出的。

场景1:如果发现该操作已经在执行中则不再执行(有状态执行)

private ReentrantLock lock = new ReentrantLock();
...
if (lock.tryLock()) { // 如果已经被lock,则立即返回false不会等待,达到忽略操作的效果
	try {
		// 操作
	} finally {
		lock.unlock();
	}
}

场景2:如果发现该操作已经在执行,等待一个一个执行(同步执行,类似synchronized)

private ReentrantLock lock = new ReentrantLock(); // 参数默认false,不公平锁
private ReentrantLock lock = new ReentrantLock(true); // 公平锁
...
try {
	lock.lock(); // 如果被其它资源锁定,会在此等待锁释放,达到暂停的效果
	// 操作
} finally {
	lock.unlock();
}

场景3:如果发现该操作已经在执行,则尝试等待一段时间,等待超时则不执行(尝试等待执行)

private ReentrantLock lock = new ReentrantLock(); // 参数默认false,不公平锁
...
try {
	if (lock.tryLock(5, TimeUnit.SECONDS)) { // 如果已经被lock,尝试等待5s,看是否可以获得锁,如果5s后仍然无法获得锁则返回false继续执行
		try {
			// 操作
		} finally {
			lock.unlock();
		}
	}
} catch (InterruptedException e) {
	e.printStackTrace(); // 当前线程被中断时(interrupt),会抛InterruptedException
}

场景4:如果发现该操作已经在执行,等待执行。这时可中断正在进行的操作立刻释放锁继续下一操作

private ReentrantLock lock = new ReentrantLock(); // 参数默认false,不公平锁
...
try {
    lock.lockInterruptibly();
    //操作
} catch (InterruptedException e) {
    e.printStackTrace();
} finally {
    lock.unlock();
}

   

什么场景下可以使用volatile替换synchronized? 

关键字volatile的主要作用是使变量在多个线程间可见,但无法保证原子性,对于多个线程访问同一个实例变量需要加锁进行同步。

volatile和synchronized区别:

  • volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰变量,synchronized可以修饰方法,以及代码块(JVM新版本发布,synchronized关键字在执行效率上有大提升,在开发中使用synchronized关键字的比率还是比较大的)
  • 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞
  • volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存的数据做同步
  • volatile解决的是变量在多个线程之间的可见性;而synchronized解决的是多个线程之间的访问资源的同步性

 

 

  • 大小: 91.7 KB
分享到:
评论

相关推荐

    concurrent-1.3.4-sources.jar

    4. **java.util.concurrent.locks** 包:这个包提供了高级锁机制,包括ReentrantLock、ReadWriteLock等。ReentrantLock可重入锁比内置的synchronized更灵活,提供了公平性和非公平性选择,以及尝试锁定、定时锁定...

    atlassian-util-concurrent-0.0.12.jar.zip

    《深入解析Atlassian Util Concurrent库:0.0.12版本》 在IT行业中,高效且可靠的并发处理是系统性能优化的关键因素之一。Atlassian公司,以其强大的协作工具如Jira、Confluence等闻名,也提供了许多开源工具来支持...

    concurrent-all-in-one.pdf

    - 乐观锁和悲观锁:乐观锁假设并发冲突少,悲观锁假设冲突多。 21. **非阻塞算法** - Lock-Free算法:基于CAS的无锁算法,实现高效的并发数据结构。 22. **Java内存模型** - 描述线程如何访问和更新内存,以及...

    backport-util-concurrent(2.2 /3.1)

    与synchronized不同,ReentrantLock支持公平锁和非公平锁策略,并且可以分离条件变量,这使得多路分支等待成为可能。 - Condition接口提供了等待/通知机制,允许更精确的线程同步。每个Lock实例可以有多个Condition...

    aduna-commons-concurrent-2.2.jar.zip

    3. **原子变量**:Aduna Commons Concurrent提供了原子类,如AtomicInteger、AtomicLong等,它们提供了原子操作,可以在不使用锁的情况下安全地更新值,这在高并发环境中尤其重要,可以减少锁的使用,提高程序执行...

    ant-learn-python-concurrent-main.zip

    "ant-learn-python-concurrent-main.zip"这个压缩包文件显然包含了关于Python并发编程的学习资料,我们将深入探讨这个主题。 首先,Python提供了多种并发模型,包括多线程(threads)、多进程(processes)以及协程...

    concurrent-1.3.4.jar

    原子操作:concurrent包提供了一些原子操作类,如AtomicInteger、AtomicLong等,可以实现无锁的线程安全操作,避免了使用锁带来的性能损耗。 线程池:concurrent包提供了Executor框架,可以方便地创建和管理线程池,...

    开源项目-streamrail-concurrent-map.zip

    开源项目“streamrail-concurrent-map.zip”是一个基于Go语言实现的高效并发映射数据结构。在Go语言中,原生的`map`类型虽然在单线程环境下性能优秀,但在多线程并发环境下可能会遇到竞态条件,导致数据不一致或程序...

    concurrent-1.3.2 connector.

    在IT行业中,"concurrent-1.3.2 connector" 提到的是一个特定版本的并发连接器,可能是某个软件框架或库的一部分。这个版本号(1.3.2)表明这是一个迭代更新,通常包含了错误修复、性能提升或者新功能的添加。在...

    实战Concurrent-BlockQueue

    《实战Concurrent-BlockQueue》 在Java并发编程领域,`Concurrent-BlockQueue`是一个重要的数据结构,它结合了线程安全与高效性能。本文将深入探讨`ConcurrentLinkedQueue`、`ArrayBlockingQueue`以及`...

    swift-Concurrent-函数式并发原语的集合

    在并发环境中,确保数据一致性是非常重要的,我们可能需要使用锁、原子操作或`@mainActor`等同步机制来避免竞态条件和数据竞争。 总之,Swift的并发编程提供了一套强大的工具,使得开发者能够构建高性能、易于理解...

    aduna-commons-concurrent-2.5.0.jar.zip

    2. **锁和同步机制**:除了Java内置的锁机制外,该库还提供了一些高级的同步工具,如可中断和定时的锁,以及条件变量,这些都可以用于构建复杂的同步逻辑,同时提高了代码的灵活性。 3. **并发容器**:库中包含了...

    concurrent-patterns-best-practices-synchronization

    2. **同步机制**:深入探讨不同的同步机制,如锁(Lock)、信号量(Semaphore)、读写锁(Read-Write Lock)等,以及它们在实际应用中的优缺点。 3. **设计模式**:介绍多种用于解决并发问题的设计模式,例如生产者...

    PyPI 官网下载 | twitter.common.concurrent-0.3.1.tar.gz

    3. **锁和信号量**:提供线程安全的数据结构,如互斥锁(Mutex)、读写锁(RLock)、信号量(Semaphore),确保多线程访问共享资源时的正确性。 4. **未来对象(Future)**:允许程序提前安排计算任务,并在任务完成...

    Concurrent - Programming in Java.pdf

    - **标准库**:Java并发工具包(java.util.concurrent)提供了丰富的并发工具类。 - **第三方库**:例如Apache Commons Concurrency等。 ##### 2. 构建库 - **自定义并发组件**:根据项目需求开发特定的并发工具。 ...

    mastering-c-multithreading-write-robust-concurrent-and-parallel

    3. **同步机制**:深入研究互斥量(mutexes)、读写锁(read-write locks)、信号量(semaphores)和条件变量,以及它们在保护共享资源中的作用。 4. **原子操作和内存模型**:探讨C++11引入的原子类型和操作,以及...

    Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf

    ConcurrentHashMap 的实现是基于哈希表的,使用了分段锁机制来实现线程安全。每个段锁都对应一个哈希表的分区,用于存储和访问数据。 ConcurrentHashMap 的实现还使用了链表和树形结构来存储和访问数据,提供了高效...

    并发编程Concurrent-Programming.pdf

    并发编程 Concurrent Programming 并发编程是计算机科学中一个非常重要的概念,它指的是在一个程序中同时执行多个任务的能力。并发编程可以提高程序的性能、响应速度和可扩展性,但它也带来了很多挑战,例如数据...

    Android-Java并发工具类库

    这个名为“Xiaofei-it-Concurrent-Utils-829a450”的压缩包可能包含了一些优化和扩展了Java标准并发库(java.util.concurrent)的实用工具类。这里我们将深入探讨一些关于Java并发编程的关键知识点,并尝试理解这个...

Global site tag (gtag.js) - Google Analytics