LOCK接口
1.大多数时候,synchronized来实现同步,但它有一些缺点,为此Java 1.5并发API包ava.util.concurrent,通过LOCK接口来提高对象锁定机制。
重要的锁API接口和类在Java中是:
Lock:这是基本接口API。它除了实现synchronized关键字的所有功能外,提供了额外的方法来创建不同的锁定, lock()得到锁, to acquire the lock, unlock() 释放当前锁, tryLock() 等待一段时间获得锁, newCondition()创造相关条件等。
Condition:Condition对象类似于对象wait-notify模型,可以创建不同的等待时间。其多由LOCK对象创立。一些重要的方法是如 await()和 wait(),signalAll()类似。signalAll()类似notify()和notifyAll()方法。
ReadWriteLock:它包含一对相关的锁,一个用于只读操作,另一个用于写操作。读锁由多个读线程可以同时举行,只要没有写线程,就是安全的。写锁是排斥的。
ReentrantLock:这是最广泛使用的锁接口的实现类。这个类实现了类似synchronized的功能。除了锁定接口实现,ReentrantLock包含一些实用方法去持有锁的线程,线程等待获取锁等。
重入锁之所以这么叫指的是同一个线程多次试图获取它所占有的锁,请求会成功。
当释放锁的时候,直到重入次数清零,锁才释放完毕。关于重入锁下面是一个简单的例子。
public class Test{
public synchronized foo(){
//do something
bar();
}
public synchronized bar(){
//do some more
}
}
如果一个线程进入foo(),那么对象获得当前锁,所以当它试图执行bar()方法,允许线程执行bar()方法,因为它已经获得Test对象上的锁。
LOCK 接口实例:
1.同步方法
package com.journaldev.threads.lock;
class Resource {
public void doSomething(){
//do some operation, DB read, write etc
}
public void doLogging(){
//logging, no need for thread safety
}
}
public class SynchronizedLockExample implements Runnable{
private Resource resource;
public SynchronizedLockExample(Resource r){
this.resource = r;
}
@Override
public void run() {
synchronized (resource) {
resource.doSomething();
}
resource.doLogging();
}
}
2.LOCK方法
package com.journaldev.threads.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConcurrencyLockExample implements Runnable{
private Resource resource;
private Lock lock;
public ConcurrencyLockExample(Resource r){
this.resource = r;
this.lock = new ReentrantLock();
}
@Override
public void run() {
try {
if(lock.tryLock(10, TimeUnit.SECONDS)){
resource.doSomething();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
//release lock
lock.unlock();
}
resource.doLogging();
}
}
注意利用
<span style="font-size:14px;">lock.tryLock(10, TimeUnit.SECONDS)</span>来对其相应控制获得锁,<span style="font-size:14px;"></span>
此外可以释放锁
lock.unlock();
3.总结(对比LOCK vs synchronized)
Lock接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。
它的优势有:
- 可以使锁更公平
- synchronized简单清晰,LOCK有try-finally 模块,还要确保释放锁
- 可以使线程在等待锁的时候响应中断
- 可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间
- 可以在不同的范围,以不同的顺序获取和释放锁