使用StampedLock替代ReentrantReadWriteLock
Posted zheaven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用StampedLock替代ReentrantReadWriteLock相关的知识,希望对你有一定的参考价值。
悲观读(写的机会很少)
package com.dwz.stampedLock; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.StampedLock; import java.util.stream.Collectors; /** * 悲观读(写的机会很少) * 100 threads * 99 threads need read lock * 1 threads need write lock * 可以使用StampedLock替代ReentrantReadWriteLock */ public class StampedLockExample { private final static StampedLock lock = new StampedLock(); private final static List<Long> DATA = new ArrayList<>(); private static void read() { long stamped = -1; try { stamped = lock.readLock(); Optional.of(DATA.stream().map(String::valueOf).collect(Collectors.joining("#", "R-", ""))) .ifPresent(System.out::println); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlockRead(stamped); } } private static void write() { long stamped = -1; try { stamped = lock.writeLock(); DATA.add(System.currentTimeMillis()); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlockWrite(stamped); } } public static void main(String[] args) { final ExecutorService executor = Executors.newFixedThreadPool(10); Runnable readTask = () -> { for(;;) { read(); } }; Runnable writeTask = () -> { for(;;) { write(); } }; executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(writeTask); } }
改进
package com.dwz.stampedLock; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.StampedLock; import java.util.stream.Collectors; /** * 乐观读(写的机会相对增多) */ public class StampedLockExample2 { private final static StampedLock lock = new StampedLock(); private final static List<Long> DATA = new ArrayList<>(); private static void read() { long stamp = lock.tryOptimisticRead(); if(lock.validate(stamp)) {//验证在该时间锁是否还持有 try { stamp = lock.readLock(); Optional.of(DATA.stream().map(String::valueOf).collect(Collectors.joining("#", "R-", ""))) .ifPresent(System.out::println); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlockRead(stamp); } } } private static void write() { long stamped = -1; try { stamped = lock.writeLock(); DATA.add(System.currentTimeMillis()); TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlockWrite(stamped); } } public static void main(String[] args) { final ExecutorService executor = Executors.newFixedThreadPool(10); Runnable readTask = () -> { for(;;) { read(); } }; Runnable writeTask = () -> { for(;;) { write(); } }; executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(readTask); executor.submit(writeTask); } }
以上是关于使用StampedLock替代ReentrantReadWriteLock的主要内容,如果未能解决你的问题,请参考以下文章