线程同步基础——使用读写锁实现同步数据访问

/**
 * 缓存器例子
 * @author Administrator
 *
 */
public class CacheDemo {
	private Map map = new HashMap<>(128);
	private ReadWriteLock rwl = new ReentrantReadWriteLock();

	public static void main(String[] args) {
			new Thread(new Runnable() {

				@Override
				public void run() {
					CacheDemo demo = new CacheDemo();
					System.out.println(Thread.currentThread().getName()+":"+demo.get("111"));

				}
			}).start();
			new Thread(new Runnable() {

				@Override
				public void run() {
					CacheDemo demo = new CacheDemo();
					System.out.println(Thread.currentThread().getName()+":"+demo.get("123"));

				}
			}).start();
			new Thread(new Runnable() {

				@Override
				public void run() {
					CacheDemo demo = new CacheDemo();
					System.out.println(Thread.currentThread().getName()+":"+demo.get("122"));

				}
			}).start();
			
			new Thread(new Runnable() {

				@Override
				public void run() {
					CacheDemo demo = new CacheDemo();
					System.out.println(Thread.currentThread().getName()+":"+demo.get("122"));
				}
			}).start();
	}

	public Object get(String id) {
		Object value = null;
		// 首先开启读锁,从缓存中去取
		rwl.readLock().lock();
		try {
			// 如果缓存中没有,就可以去数据库查询并保存到缓存中(需要写操作,所以加写锁)
			if (map.get(id) == null) { 
				//释放读锁
				rwl.readLock().unlock();
				//上写锁
				rwl.writeLock().lock();
				try {
					// 防止多写线程重复查询赋值
					if (value == null) { 
						// 此时可以去数据库中查找,这里简单的模拟一下
						value = "redis-value"+id; 
						map.put(id, value);
					}
					// 加读锁降级写锁,因为写操作完毕,所以可以降级写锁,加读锁
					rwl.readLock().lock(); 
				} finally {
					// 释放写锁
					rwl.writeLock().unlock(); 
				}
			} else {
				//缓存中有,直接获取
				value = map.get(id);
			}
		} finally {
			// 最后释放读锁
			rwl.readLock().unlock(); 
		}
		return value;
	}
}

/**
 * 共享list的列子
 * @author Administrator
 *
 */
public class ShareData {
	ArrayList data = new ArrayList<>();
	private ReadWriteLock rw = new ReentrantReadWriteLock();
	
	/**
	 * 读取数据使用读锁
	 * @param i
	 * @return
	 */
	public String get(int i){
		rw.readLock().lock();
		String str = null;
		try {
			str = data.get(i);
		} catch (Exception e) {
			rw.readLock().unlock();
		}
		return str;
	}
	
	/**
	 * 添加数据用写锁
	 * @param str
	 */
	public void add(String str){
		rw.writeLock().lock();
		try {
			data.add(str);
		} catch (Exception e) {
			rw.writeLock().unlock();
		}
	}
}

你可能感兴趣的:(web后端,windows,并发编程)