码迷,mamicode.com
首页 > 编程语言 > 详细

java中的锁

时间:2015-07-13 15:27:06      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

内置锁 sychronizedvolatile

1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。 

2.volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的 

3.volatile仅能实现变量的修改可见性,并能保证原子性;而synchronized则可以保证变量的修改可见性和原子性 

4.volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。 

5.volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化 

 

显示锁

显示锁

    在JDK5之前,可使用的同步机制只有synchronized 关键字和volative变量,JDK5增加了一种新的锁机制:ReentrantLock, ReentrantLock并不是替代内置锁的方法,而是当内置锁机制不适用时作为一种可选择的高级功能。

    JDK5提供的锁工具类都在java.util.concurrent.locks包下,有Condition、Lock、ReadWriteLock等接口:

Lock : 接口支持那些语义不同(重入、公平等)的锁规则,可以在非阻塞式结构的上下文(包括 hand-over-hand 和锁重排算法)中使用这些规则。主要的实现是 ReentrantLock 。

 1 public class Counter{
 2     private Lock lock = new Lock();
 3     private int count = 0;
 4 
 5     public int inc(){
 6         lock.lock();
 7         int newCount = ++count;
 8         lock.unlock();
 9         return newCount;
10     }
11 }

lock()方法会对Lock实例对象进行加锁,因此所有对该对象调用lock()方法的线程都会被阻塞,直到该Lock对象的unlock()方法被调用。

ReadWriteLock : 读写锁接口以类似方式定义了一些读取者可以共享而写入者独占的锁。此包只提供了一个实现,即 ReentrantReadWriteLock ,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的、适用于非标准要求的实现。

Condition : 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。

    在大多数情况下,显示锁都能很好的工作,但有些局限性,如无法中断一个正在等待获取锁的线程,或者无法在请求获取一个锁时无限的等待下去。Lock提供了一种无条件的、可轮询的、定时的以及可中断的锁获取操作,所有加锁和解锁的方式都是显示的。下面代码给出了Lock接口使用的标准形式,必须在finally中释放锁:

1 Lock lock = new ReentrantLock();  
2 ...  
3 lock.lock();//显示加锁  
4 try{  
5     ...  
6 }finally{  
7     //显示释放锁  
8     lock.unlock();  
9 }  

 boolean tryLock()接口实现可定时与可轮询获取锁的实现,与无条件获取锁的模式相比,它具有更完善的错误恢复机制,在内置锁中,死锁是一种严重的问题,恢复程序的唯一方法就是重启应用,而防止死锁的方法就是在构造程序时避免出现不一致的锁顺序。可定时与可轮询提供了另一种方式:避免死锁的发生。下面代码实现了可轮询获取锁,如果不能同时获得两个锁,那么就退回重试:

 1 public boolean transferMoney(Account fromAcct, Account toAcct) {  
 2     while (true) {  
 3         if (fromAcct.lock.tryLock()) {  
 4             try {  
 5                 if (toAcct.lock.tryLock()) {  
 6                     try {  
 7                         ...  
 8                     }  
 9                     finally {  
10                         toAcct.lock.unlock();  
11                     }  
12                 }  
13             }  
14             finally {  
15                 fromAcct.lock.unlock();  
16             }  
17         }  
18     }  
19 }  

读写锁:由JVM控制,保证读跟写的互斥。

下面为用读-写锁来包装的Map类

 1 package thread;  
 2   
 3 import com.sun.org.apache.bcel.internal.generic.NEW;  
 4   
 5 import java.util.Map;  
 6 import java.util.concurrent.locks.Lock;  
 7 import java.util.concurrent.locks.ReadWriteLock;  
 8 import java.util.concurrent.locks.ReentrantReadWriteLock;  
 9   
10 /** 
11  * @description 
12  *  
13  * @author chenzehe 
14  * @email hljuczh@163.com 
15  * @create 2013-1-9 下午09:05:58 
16  */  
17   
18 public class ReadWriteMap<K, V> {  
19     private final Map<K, V>       map;  
20     private final ReadWriteLock lock    = new ReentrantReadWriteLock();  
21     private final Lock          r       = lock.readLock();  
22     private final Lock          w       = lock.writeLock();  
23       
24     public ReadWriteMap(Map<K, V> map) {  
25         this.map = map;  
26     }  
27       
28     public V put(K key, V value) {  
29         w.lock();  
30         try {  
31             return map.put(key, value);  
32         }  
33         finally {  
34             w.unlock();  
35         }  
36     }  
37       
38     public V get(Object key) {  
39         r.lock();  
40         try {  
41             return map.get(key);  
42         }  
43         finally {  
44             r.unlock();  
45         }  
46     }  
47 }  

 

java中的锁

标签:

原文地址:http://www.cnblogs.com/fuxiaoshenjian/p/4642764.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!