java并发编程(9)--java线程锁技术Lock&ReadWriteLock

来源:互联网 发布:诺基亚e71软件 编辑:程序博客网 时间:2024/06/07 18:16

1.Lock

比传统线程模型中的synchronized方式更加面向对象,和生活中的锁类似,锁本身也应该是一个对象,两个线程执行的代码片段要实现同步互斥的效果,他们必须用同一个Lock对象

eg:改进传统的线程同步

package com.qunar.thread;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ThreadLock {public static void main(String[] args) {new ThreadLock().init();}private  void init() {final Outputer outputer = new Outputer();new Thread(new Runnable() {public void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}outputer.output("suhao");}}}).start();new Thread(new Runnable() {public void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}outputer.output("liushourun");}}}).start();}static class Outputer {Lock lock = new ReentrantLock();public void output(String name) {int len = name.length();lock.lock();try {for (int i = 0; i < len; i++) {System.out.print(name.charAt(i));}System.out.println();} catch (Exception e) {}finally{lock.unlock();}}}}

2.读写锁:

读写互斥 写写互斥 读读不互斥

由JVM自己控制,只要加上对应的锁就行了。

eg:

package com.qunar.thread;import java.util.Random;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadAndWriteLock {public static void main(String[] args) {final Queue3 q3 = new Queue3();for(int i = 0;i<3;i++){new Thread(new Runnable() {@Overridepublic void run() {while (true) {q3.get();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {q3.put(new Random().nextInt(10000));}}}).start();}}}class Queue3{private Object dataObject;ReadWriteLock rwlLock = new ReentrantReadWriteLock();public void get(){rwlLock.readLock().lock();try {System.out.println(Thread.currentThread().getName()+"be ready to read data");Thread.sleep((long)(Math.random()*1000));System.out.println(Thread.currentThread().getName()+ "have read data"+dataObject);} catch (Exception e) {e.printStackTrace();}finally{rwlLock.readLock().unlock();}}public void put(Object data){rwlLock.writeLock().lock();try {System.out.println(Thread.currentThread().getName()+ "be ready to write data");Thread.sleep((long)(Math.random()*1000));this.dataObject = data;System.out.println(Thread.currentThread().getName()+ "have write data"+data);} catch (Exception e) {e.printStackTrace();}finally{rwlLock.writeLock().unlock();}}}

3.实现一个缓存 系统

示例用法。下面的代码展示了如何利用重入来执行升级缓存后的锁降级(为简单起见,省略了异常处理):

 class CachedData {   Object data;   volatile boolean cacheValid;   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();   void processCachedData() {     rwl.readLock().lock();     if (!cacheValid) {        // Must release read lock before acquiring write lock        rwl.readLock().unlock();        rwl.writeLock().lock();        // Recheck state because another thread might have acquired        //   write lock and changed state before we did.        if (!cacheValid) {          data = ...          cacheValid = true;        }        // Downgrade by acquiring read lock before releasing write lock        rwl.readLock().lock();        rwl.writeLock().unlock(); // Unlock write, still hold read     }     use(data);     rwl.readLock().unlock();   } }

实际实现

import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * 缓存系统,使用读写锁实现 * @author hao.su * */public class CacheDemo {private Map<String, Object> cache = new HashMap<String, Object>();private ReadWriteLock rwl = new ReentrantReadWriteLock();/** * 多个线程之间可以并发的读, * @param key * @return */public  Object getData(String key) {rwl.readLock().lock();Object data = null;try {data = cache.get(key);if (data == null) {rwl.readLock().unlock();rwl.writeLock().lock();if(data == null){try{data = "aaaa";// 到数据库中查找}finally{rwl.writeLock().unlock();}}rwl.readLock().lock();}} catch (Exception e) {e.printStackTrace();}finally{rwl.readLock().unlock();}return data;}}




0 0
原创粉丝点击