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

本文深入探讨了Java中的Lock接口及其实现ReentrantLock,并通过示例介绍了如何利用锁来改进传统线程同步方法。此外,还讲解了读写锁的概念及其应用场景,包括如何在缓存系统中使用读写锁来提高并发性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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() {
				
				@Override
				public void run() {
					while (true) {
						q3.get();
					}
				}
			}).start();
			new Thread(new Runnable() {
				
				@Override
				public 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;
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值