欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java读写锁

程序员文章站 2022-05-04 17:17:25
...

读写锁

假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。Java5在java.util.concurrent包中已经包含了读写锁。尽管如此,我们还是应该了解其实现背后的原理。
这里有个小例子,就是让写入的时候,不要出现读,我们模拟一个cache的一个缓冲例子:
package com.newDemo.controller.test;

import java.util.HashMap;
import java.util.Map;

public class threadDemo28 {

	static Map<String, Object> map = new HashMap<String, Object>();

	// 获取一个key对应的value
	public static final Object get(String key) {
		System.out.println("正在做读的操作,key:" + key + " 开始");
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Object object = map.get(key);
		System.out.println("正在做读的操作,key:" + key + " 结束");
		System.out.println();
		return object;
	}

	// 设置key对应的value,并返回旧有的value
	public static final Object put(String key, Object value) {

		System.out.println("正在做写的操作,key:" + key + ",value:" + value + "开始.");
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Object object = map.put(key, value);
		System.out.println("正在做写的操作,key:" + key + ",value:" + value + "结束.");
		System.out.println();
		return object;
	}
	
	
	public static void main(String[] args) {
		new Thread(new Runnable() {

			public void run() {
				for (int i = 0; i < 10; i++) {
					threadDemo28.put(i + "", i + "");
				}

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

			public void run() {
				for (int i = 0; i < 10; i++) {
					threadDemo28.get(i + "");
				}

			}
		}).start();
	}

}

效果如下:
java读写锁
这个地方就出现了在写的时候,有读的现象。所以说我们用读写锁ReentrantReadWriteLock

package com.newDemo.controller.test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class threadDemo29 {

	static Map<String, Object> map = new HashMap<String, Object>();
	static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	static Lock r = rwl.readLock();
	static Lock w = rwl.writeLock();

	// 获取一个key对应的value
	public static final Object get(String key) {
		Object object = null;
		try {
			r.lock();
			System.out.println("正在做读的操作,key:" + key + " 开始");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			object = map.get(key);
			System.out.println("正在做读的操作,key:" + key + " 结束");
			System.out.println();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			r.unlock();
		}
		return object;
	}

	// 设置key对应的value,并返回旧有的value
	public static final Object put(String key, Object value) {

		Object object = null;
		try {
			w.lock();
			System.out.println("正在做写的操作,key:" + key + ",value:" + value + "开始.");
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			object = map.put(key, value);
			System.out.println("正在做写的操作,key:" + key + ",value:" + value + "结束.");
			System.out.println();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			w.unlock();
		}
		return object;
	}
	
	
	public static void main(String[] args) {
		new Thread(new Runnable() {

			public void run() {
				for (int i = 0; i < 10; i++) {
					threadDemo29.put(i + "", i + "");
				}

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

			public void run() {
				for (int i = 0; i < 10; i++) {
					threadDemo29.get(i + "");
				}

			}
		}).start();
	}

}

结果如下:
java读写锁
这个地方就是读写分离了,保证了线程的安全性。

相关标签: 线程池