12-Java5读写锁技术的妙用
只要有写就要互斥,否则就要有问题,如果都是读那么就没问题
都是读就不要锁了,否则影响性能
package cn.itcast.demo.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 BusinessService businessService = new BusinessService(); for (int i=0; i<3; i++) { // 读 new Thread(new Runnable() { @Override public void run() { while (true) { businessService.get(); } } }).start(); // 写 new Thread(new Runnable() { @Override public void run() { while (true) { int data = new Random().nextInt(10000); businessService.put(data); } } }).start(); } } } class BusinessService { private Object data; ReadWriteLock rwLock = new ReentrantReadWriteLock(); // 读 public void get() { rwLock.readLock().lock(); try { System.out.println("==========================================" + Thread.currentThread().getName() + " is ready to read data..."); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " has red data: " + this.data); } catch (Exception e) { e.printStackTrace(); } finally { rwLock.readLock().unlock(); } } // 写 public void put(Object data) { rwLock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " is ready to 【write】..."); Thread.sleep(1000); this.data = data; System.out.println(Thread.currentThread().getName() + " has 【wrote】 data: " + this.data); } catch (Exception e) { e.printStackTrace(); } finally { rwLock.writeLock().unlock(); } } }
打印结果:
==========================================Thread-0 is ready to read data... ==========================================Thread-2 is ready to read data... ==========================================Thread-4 is ready to read data... Thread-0 has red data: null Thread-4 has red data: null Thread-2 has red data: null Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 7204 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 3655 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 5606 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 975 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 9057 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 2011 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 2788 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 2383 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 819 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 1529 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 3665 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 252 ==========================================Thread-0 is ready to read data... ==========================================Thread-4 is ready to read data... ==========================================Thread-2 is ready to read data... Thread-4 has red data: 252 Thread-0 has red data: 252 Thread-2 has red data: 252 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 6139 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 6386 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 9229 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 9532 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 6713 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 7474 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 8841 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 1590 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 3066 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 2454 ==========================================Thread-4 is ready to read data... ==========================================Thread-0 is ready to read data... ==========================================Thread-2 is ready to read data... Thread-2 has red data: 2454 Thread-0 has red data: 2454 Thread-4 has red data: 2454 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 4301 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 6942 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 3463 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 4326 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 127 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 3896 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 7426 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 9235 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 1826 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 512 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 9695 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 5217 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 4643 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 6613 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 7693 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 3476 Thread-1 is ready to 【write】... Thread-1 has 【wrote】 data: 8197 ==========================================Thread-0 is ready to read data... ==========================================Thread-4 is ready to read data... ==========================================Thread-2 is ready to read data... Thread-2 has red data: 8197 Thread-4 has red data: 8197 Thread-0 has red data: 8197 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 4247 Thread-3 is ready to 【write】... Thread-3 has 【wrote】 data: 3827 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 1665 Thread-5 is ready to 【write】... Thread-5 has 【wrote】 data: 5349 Thread-5 is ready to 【write】...
写一个缓存系统的Demo
package cn.itcast.demo.thread; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class CacheDemo { public static void main(String[] args) { CacheService cacheService = new CacheService(); Object value = cacheService.getData("hello"); System.out.println(value); } } class CacheService { private Map<String, Object> cache = new HashMap<String, Object>(); private ReadWriteLock rwLock = new ReentrantReadWriteLock(); public Object getData(String key) { rwLock.readLock().lock(); Object value = null; try { value = cache.get(key); // 多线程并发访问的时候,如果任何一个线程发现数据为空,就不让其他线程再进行读写操作 if (value == null) { // 不让其他线程读 rwLock.readLock().unlock(); // 同时开启写锁 rwLock.writeLock().lock(); try { if (value == null) { // 第一个线程进来发现是空,就进行写操作,以后的线程进来发现数据不为空就不进行写操作 System.out.println("查数据库..."); value = "aaaa"; // 实际去查询数据库 } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭写锁 rwLock.writeLock().unlock(); } // 重新开启读锁 rwLock.readLock().lock(); } } catch (Exception e) { e.printStackTrace(); } finally { rwLock.readLock().unlock(); } return value; } }