天天看点

Java之多线程之Lock与Condition

[color=green][size=medium][b]Java之多线程之Lock[/b][/size][/color]

[url=http://lixh1986.iteye.com/blog/2351243]接上文[/url]

在多线程环境中,大部分情况下,使用 synchronized 关键字可以满足需求。

但是其也存在不足。于是 java.util.concurrent.locks 包出现了。

[size=medium][b]一、Lock API 的主要类介绍[/b][/size]

[b]1、Lock 接口 - 实现类 ReentrantLock[/b]

接口类。规定了Lock的基本方法,这些方法可以满足所有 synchronized 的功能,

还提供了更多功能:Lock条件判断、Lock超时判断。

其最主要的方法:

lock():获取锁

unlock():释放锁

tryLock():等待锁一段时间再锁

newCondition():根据条件进行锁

[b]1.1 Condition[/b]

背景知识:

- wait()、notify()

在多线程进行协同工作时,需要用到 wait()、notify() 。

wait()、notify() 只能用在 synchronized 块内部,而且是,synchronized 哪个对象,就得调用哪个对象的 wait()、notify() 方法。

Condition 类与Object类的 wait()、notify() 方法功能差不多。

但是提供了更多:可以创建不同的 wait 集合。

Condition 的实例必须由 Lock 类创建,而不是自己去 new 而产生。

主要方法:

await():类似于 Object.wait()

signal():类似于 Object.notify()

signalAll():类似于 Object.notifyAll()

[b]1.2 ReentrantLock[/b]

该类被使用的最为广泛。它是在功能上实现了 synchronized 的类。

除了实现了从 Lock 接口继承的方法,它还自己有一些方法:

比如让线程等待一段时间再去获取资源的锁。

[b]什么是 reentrant (可重入)?[/b]

其实 synchronized 代码块原本就是可重入(reentrant)的:

例如:

某线程正在执行 synchronized 代码块一,代码块一中需要执行代码块二,

两个代码块锁定的是同一个资源,此时线程一可以顺利执行此两个代码块。

无需重复获取资源的锁,即:资源锁重用。

看下面的例子:

线程在执行 foo()时,需要执行 bar(),此时直接执行即可,无需重复获取锁。

因为这两个 synchronized 代码块锁定的是同一个对象:this

[b]2、ReadWriteLock 接口 - 实现类 ReentrantReadWriteLock[/b]

该类包含了一对相互关联的锁。

一种是:只读锁(Read-Only)。如果没有其它线程在占有写锁,该锁可以被多个线程同时拥有。

一种是:写锁。如果没有线程在占有读锁或写锁,该锁只能被一个线程独占。

[size=medium][b]二、Lock 使用示例[/b][/size]

1、先看看用 synchronized 的写法:

2、使用 java.util.concurrent.locks.Lock 的写法:

3、ReentrantReadWriteLock

4. [url=https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html]ReentrantReadWriteLock [/url] 使用Lock 实现缓存。

5. 双condition实现的阻塞式消息队列。

6. 使用 3 个 condition,使每个子线程各自交替执行。

7. Semaphore

Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

比如在Windows下可以设置共享文件的最大客户端访问个数。

java.util.concurrent包之Execuotor系列文章

[url=http://lixh1986.iteye.com/blog/2341898]00_Java之 java.util.concurrent 包之概述[/url]

[url=http://lixh1986.iteye.com/blog/2360304]01_Java之java.util.concurrent包之Executor与ExecutorService[/url]

[url=http://lixh1986.iteye.com/blog/2360306]02_Java之 java.util.concurrent 包之ExecutorService之submit () 之 Future[/url]

[url=http://lixh1986.iteye.com/blog/2351367]03_Java之多线程之Callable与Future[/url]

[url=http://lixh1986.iteye.com/blog/2351294]04_Java之多线程之Lock[/url]

-

转载请注明,

原文出处:http://lixh1986.iteye.com/blog/2351294

引用:

http://www.journaldev.com/2377/java-lock-example-reentrantlock