并发包下锁的一些应用
作者:互联网
前言:在并发中,最熟悉的JUC编程,问的最多的也是下面四个包,随手写篇博客记录日常中的学习一下!
一、读写锁
java.util.concurrent.locks.ReentrantReadWriteLock;
ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。
所有读写锁的实现必须确保写操作对读操作的内存影响。换句话说,一个获得了读锁的线程必须能看到前一个释放的写锁所更新的内容。
读写锁比互斥锁允许对于共享数据更大程度的并发。每次只能有一个写线程,但是同时可以有多个线程并发地读数据。ReadWriteLock适用于读多写少的并发情况。
举个例子,有六个线程进行读写操作,但是呢,我们在写入数据的时候是并不希望有别的线程来加塞,我们在读取的时候可以多个线程进行读取:
1 import java.util.HashMap; 2 import java.util.Map; 3 import java.util.concurrent.TimeUnit; 4 import java.util.concurrent.locks.ReadWriteLock; 5 import java.util.concurrent.locks.ReentrantReadWriteLock; 6 7 /** 8 * @author zhangzhixi 9 * @date 2021-4-18 22:25 10 */ 11 public class Demo_01_读写锁 { 12 public static void main(String[] args) { 13 MyCache myCache = new MyCache(); 14 // 六个写的线程 15 for (int i = 1; i <= 6; i++) { 16 final int temp = i; 17 new Thread(() -> { 18 myCache.put(temp + "", temp + ""); 19 }, String.valueOf(i)).start(); 20 } 21 // 六个读的线程 22 for (int i = 1; i <= 6; i++) { 23 final int temp = i; 24 new Thread(() -> { 25 myCache.get(temp + ""); 26 }, String.valueOf(i)).start(); 27 } 28 } 29 } 30 31 /** 32 * 定义缓存类 33 */ 34 class MyCache { 35 volatile Map<String, Object> map = new HashMap<>(); 36 37 public void put(String key, String value) { 38 System.out.println(Thread.currentThread().getName() + "\t 正在写入" + key); 39 // 模拟网络延迟 40 try { 41 TimeUnit.MICROSECONDS.sleep(300); 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 map.put(key, value); 46 System.out.println(Thread.currentThread().getName() + "\t 写入完成"); 47 } 48 49 public void get(String key) { 50 // 模拟网络延迟 51 try { 52 TimeUnit.MICROSECONDS.sleep(200); 53 } catch (InterruptedException e) { 54 e.printStackTrace(); 55 } 56 Object value = map.get(key); 57 System.out.println(Thread.currentThread().getName() + "\t 读取完成->" + value); 58 } 59 }
通过上面的测试可以看到,线程在写入数据的时候,有其他线程过来加塞。
改进后的读写锁代码:
1 import java.util.HashMap; 2 import java.util.Map; 3 import java.util.concurrent.TimeUnit; 4 import java.util.concurrent.locks.ReadWriteLock; 5 import java.util.concurrent.locks.ReentrantReadWriteLock; 6 7 /** 8 * @author zhangzhixi 9 * @date 2021-4-18 22:25 10 */ 11 public class Demo_01_读写锁 { 12 public static void main(String[] args) { 13 MyCache myCache = new MyCache(); 14 // 六个写的线程 15 for (int i = 1; i <= 6; i++) { 16 final int temp = i; 17 new Thread(() -> { 18 myCache.put(temp + "", temp + ""); 19 }, String.valueOf(i)).start(); 20 } 21 // 六个读的线程 22 for (int i = 1; i <= 6; i++) { 23 final int temp = i; 24 new Thread(() -> { 25 myCache.get(temp + ""); 26 }, String.valueOf(i)).start(); 27 } 28 } 29 } 30 31 /** 32 * 定义缓存类 33 */ 34 class MyCache { 35 volatile Map<String, Object> map = new HashMap<>(); 36 ReadWriteLock lock = new ReentrantReadWriteLock(); 37 public void put(String key, String value) { 38 // 写入数据 39 lock.writeLock().lock(); 40 try { 41 System.out.println(Thread.currentThread().getName() + "\t 正在写入" + key); 42 // 模拟网络延迟 43 try { 44 TimeUnit.MICROSECONDS.sleep(300); 45 } catch (InterruptedException e) { 46 e.printStackTrace(); 47 } 48 map.put(key, value); 49 System.out.println(Thread.currentThread().getName() + "\t 写入完成"); 50 } catch (Exception e) { 51 e.printStackTrace(); 52 } finally { 53 lock.writeLock().unlock(); 54 } 55 } 56 57 public void get(String key) { 58 lock.readLock().lock(); 59 try { 60 System.out.println(Thread.currentThread().getName() + "\t 正在读取" + key); 61 // 模拟网络延迟 62 try { 63 TimeUnit.MICROSECONDS.sleep(200); 64 } catch (InterruptedException e) { 65 e.printStackTrace(); 66 } 67 Object value = map.get(key); 68 System.out.println(Thread.currentThread().getName() + "\t 读取完成->" + value); 69 } catch (Exception e) { 70 e.printStackTrace(); 71 } finally { 72 lock.readLock().unlock(); 73 } 74 } 75 }
二、倒计时锁存器
标签:key,下锁,java,String,util,线程,应用,import,发包 来源: https://www.cnblogs.com/zhangzhixi/p/14676057.html