您的位置:首页 > 编程语言 > Java开发

Java多线程学习笔记3——ReentranLock和ReentrantReadWriteLock

2018-03-01 16:59 471 查看
在java中实现的同步的方式有synchronized方法,synchronized代码块,ReentranLock,ReentrantReadWriteLock,
主要功能是在多线程的环境下实现代码的同步。
synchronized方法,有一定的局限性作用的区域受限,有时代码可能只需要方法中某一行或者几行代码要同步,不许要整个方法同步影响程序性能或则造成程序错误。这个时候可以使用synchronized代码块,而且代码块有更灵活的锁机制可以使用自定义的对象作为锁,也可以使用当前对象作为锁。下面对比下 lock 和  synchronized:

1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现发象生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。5)Lock可以提高多个线程进行读操作的效率。 ReentrantReadWriteLock更是可以对读写两种不同的情况分别加锁。具体情景如下:写的时候不能读取数据,而且写之间是互斥的,读的时候不互斥。代码如下:public class ReadWriterLock {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.get();
}
};
}.start();
new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
};
}.start();
}
}
}
class Queue3 {
private Object data = 0;
private ReadWriteLock rwL = new ReentrantReadWriteLock();
public void get() {
rwL.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " ready read data!");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "have read data!"+this.data.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwL.readLock().unlock();
}
}
public void put(Object data) {
rwL.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " ready write data!");
this.data = data;
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "have write data!"+this.data.toString());
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
rwL.writeLock().unlock();
}
}
}以上实现了写和读之间的互斥。使用此特点可以设计一个缓存系统:代码如下ConcurrentHashMap<String, String> hashMap=new ConcurrentHashMap<>();

public String get(String key){
ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
readWriteLock.readLock().lock();
if(hashMap.containsKey(key)){
return hashMap.get(key);
}else{
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
String db=null;
if(!hashMap.containsKey(key)){
db=new Random()+"123aaa";
hashMap.put(key,db);
}
readWriteLock.writeLock().unlock();
return db;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程