其他分享
首页 > 其他分享> > 并发包下锁的一些应用

并发包下锁的一些应用

作者:互联网

前言:在并发中,最熟悉的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