当前位置: 首页 > news >正文

双峰做网站/爱站关键词挖掘工具

双峰做网站,爱站关键词挖掘工具,如何做电子海报在网站,刷钻业务推广网站文章目录前言简介案例无锁情况下使用 ReentrantLock 加锁ReentrantReadWriteLock 读写锁前言 代码中,针对加锁的区块,多线程执行调用时,会根据先获取到锁先执行,其他线程必须等待其成功释放锁后才能继续使用资源。 整体而言虽然…

文章目录

    • 前言
    • 简介
    • 案例
      • 无锁情况下
      • 使用 ReentrantLock 加锁
      • ReentrantReadWriteLock 读写锁

前言

代码中,针对加锁的区块,多线程执行调用时,会根据先获取到锁先执行,其他线程必须等待其成功释放锁后才能继续使用资源。

整体而言虽然保证了数据的完整性,但是对于效率来说,会有所降低。针对此问题,在JUC包下存在一个读写锁类ReadWriteLock

简介

ReadWriteLock在java中是一个接口。有且仅有一个官方定义的子类java.util.concurrent.locks.ReentrantReadWriteLock
在这里插入图片描述
JDK 1.8开发文档中的介绍得知,针对读锁操作,允许多个线程同时执行;针对写操作,只允许线程依次执行。
在这里插入图片描述

下面看一个栗子。

案例

无锁情况下

多线程操作一个缓存类,同时执行添加获取操作,代码案例如下所示:

package demo5_2;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;public class NoLockTest {public static void main(String[] args) throws InterruptedException {// 缓存只能单例,让多个线程同时操作一个资源,才会有并发安全问题MyNoLockCache myNoLockCache = new MyNoLockCache();// 1、开启多个线程进行写操作for (int i = 1; i <= 20 ; i++) {// 临时变量final int temp = i;new Thread(()->{myNoLockCache.set(String.valueOf(temp),"66666");},String.valueOf(i)).start();}TimeUnit.SECONDS.sleep(4);// 2、多个线程读操作for (int i = 1; i <= 20 ; i++) {// 临时变量final int temp = i;new Thread(()->{myNoLockCache.get(String.valueOf(temp));},String.valueOf(i)).start();}}/*** 没有锁的时候,设置总会被插队,导致日志打印不整齐;<br />*/
}
/*** 自定义缓存类,实现数据的  保存  和 获取操作*/
class MyNoLockCache{// 由于需要保存数据,此处采取集合的方式存储private  Map<String,Object> maps = new HashMap<>();public void set(String key,Object value){System.out.println("当前为  "+key+" 进行数据存储");maps.put(key,value);System.out.println("当前为  "+key+" 数据保存 OK");}public void get(String key){System.out.println(key+" 获取数据");maps.get(key);System.out.println(key+" 获取数据  OK");}
}

其中运行日志如下所示:
在这里插入图片描述
在这里插入图片描述

没有加锁的情况下,添加数据至缓存中,总会出现其他线程插队的现象。

使用 ReentrantLock 加锁

为了保证写入数据操作执行时,其他线程不会对其进行干扰操作,此时需要在setget方法中添加锁,保证顺序执行。

package demo5_2;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockTest {public static void main(String[] args) throws InterruptedException {// 缓存只能单例,让多个线程同时操作一个资源,才会有并发安全问题MyLockCache myLockCache = new MyLockCache();// 1、开启多个线程进行写操作for (int i = 1; i <= 30 ; i++) {// 临时变量final int temp = i;new Thread(()->{myLockCache.set(String.valueOf(temp),"66666");},String.valueOf(i)).start();}// 这里的时间只是为了测试,时间越长只是将读和写分开。// 测试读、写操作交替执行导致的问题现象可以频闭此延迟!TimeUnit.SECONDS.sleep(4);// 2、多个线程读操作for (int i = 1; i <= 30 ; i++) {// 临时变量final int temp = i;new Thread(()->{myLockCache.get(String.valueOf(temp));},String.valueOf(i)).start();}}
}/*** 自定义缓存类,实现数据的  保存  和 获取操作*/
class MyLockCache{// 由于需要保存数据,此处采取集合的方式存储private  Map<String,Object> maps = new HashMap<>();// 生成对象资源的时候  就创建一把锁private Lock lock = new ReentrantLock();public void set(String key,Object value){this.lock.lock();try {System.out.println("当前为  "+key+" 进行数据存储");maps.put(key,value);System.out.println("当前为  "+key+" 数据保存 OK");}finally {this.lock.unlock();}}public void get(String key){// 当读操作不加锁,会在写操作中插队!this.lock.lock();try {System.out.println(key+" 获取数据");Object o = maps.get(key);System.out.println(key+" 获取数据  OK  = "+o);}finally {this.lock.unlock();}}
}

执行后,控制台日志打印信息如下所示:
在这里插入图片描述

读写操作都能打印添加(获取)数据和添加(获取)ok,

但是,读操作也进行了加锁,当只是读操作执行,此时并不需要进行加锁,加了锁反而影响了执行效率。

[疑问:]到这里可能有人会问:

既然读操作加了锁影响了效率,那读操作就不加锁嘛。

但是结合之前解释的八锁效应,读操作不加锁和写操作加锁,那么读操作会插队至写操作!

ReentrantReadWriteLock 读写锁

为了保证数据写入顺序性,必须要求在以下状态下加锁和无锁:

  • 读 - 读 操作:
    读操作,只是从Map集合中获取数据,有就返回数据信息,无数据则返回null。并无并发问题,所以不需要加锁
  • 读 - 写 操作:
    考虑到多个线程同时执行,读操作无锁,但写操作必须加锁保证数据操作安全行;结合来看就必须保证同时进行读写操作需要加锁
  • 写 - 写 操作
    写和写操作之间,必须保证每个线程操作执行时的安全问题,需要加锁

使用 ReentrantReadWriteLock就能完美解决上述问题。

看下面栗子:

package demo5_2;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockTest {public static void main(String[] args) throws InterruptedException {// 缓存只能单例,让多个线程同时操作一个资源,才会有并发安全问题MyRWLock myRWLock = new MyRWLock();// 1、开启多个线程进行写操作for (int i = 1; i <= 10 ; i++) {// 临时变量final int temp = i;new Thread(()->{myRWLock.set(String.valueOf(temp),"66666");},String.valueOf(i)).start();}// 时间的长短  取决于测试  写-读 还是 单读,可以分别设定不同时间测试效果TimeUnit.SECONDS.sleep(2);// 2、多个线程读操作for (int i = 1; i <= 10 ; i++) {// 临时变量final int temp = i;new Thread(()->{myRWLock.get(String.valueOf(temp));},String.valueOf(i)).start();}}
}
class MyRWLock{// 由于需要保存数据,此处采取集合的方式存储private Map<String,Object> maps = new HashMap<>();// ReentrantReadWriteLock 创建读写锁private ReadWriteLock readWriteLock = new ReentrantReadWriteLock() ;public void set(String key,Object value){// 创建写锁this.readWriteLock.writeLock().lock();try {System.out.println("当前为  "+key+" 进行数据存储");maps.put(key,value);System.out.println("当前为  "+key+" 数据保存 OK");}finally {this.readWriteLock.writeLock().unlock();}}public void get(String key){// 创建读锁this.readWriteLock.readLock().lock();try {System.out.println(key+" 获取数据");maps.get(key);System.out.println(key+" 获取数据  OK");}finally {this.readWriteLock.readLock().unlock();}}
}

在这里插入图片描述
在这里插入图片描述
[发现:]
1、当设置延迟时间保证写操作和读操作分开执行时。日志如下:
在这里插入图片描述
在这里插入图片描述

写操作会有顺序(写和写ok)一一对应!
读操作则不会对应!
读写锁,写-写会加锁、读-读不会有锁。

2、取消延迟,测试写-读
在这里插入图片描述

即使出现写操作中插队有读操作,但日志操作执行执行ok一一对应的,说明在写-读操作中存在锁!

http://www.lbrq.cn/news/1363429.html

相关文章:

  • wordpress集成收藏功能/东莞百度快速排名优化
  • 河北企业网站建设公司/网站分析
  • 平凉市建设局门户网站/中国十大网站有哪些
  • 网站死循环/想要网站推广页
  • 做类似淘宝的网站开发需要什么/免费使用seo软件
  • 朝阳专业网站建设/seo优化的内容有哪些
  • 网络工作室主要工作内容/aso安卓优化
  • 郑州开发app公司哪家好/搜索引擎优化专员
  • 河南省建设厅举报网站/怎样去推广自己的网店
  • 如何创建网站目录/永久域名查询
  • 问鼎电子娱乐下载官方网站/关键词排名优化公司哪家强
  • 武汉光谷做网站价格/网站推广的常用途径有哪些
  • 张家口建设局网站/营销型网站建设方案
  • 阳江网站建设/windows优化大师破解版
  • 高明网站建设哪家好/网络营销平台都有哪些
  • 手机网站建设 小程序/石家庄最新新闻事件
  • 做水军那些网站好/抖音搜索引擎优化
  • 公司培训网站建设/google应用商店
  • 动态ip做网站影响seo吗/宁波seo网络推广定制多少钱
  • wordpress 做音乐网站/想做网络推广如何去做
  • 网上哪个网站做的系统好用吗/网页代码
  • 做国际网站的流程/长春seo排名扣费
  • node做网站/软文网
  • rss 网站插件/网站优化培训
  • 可以挣钱的网站/网站的搜索引擎
  • 吴中企业建设网站报价/网站推广技巧和方法
  • 企业网站优化外包/自媒体135的网站是多少
  • 深圳专业商城网站设计制作/网站更新seo
  • 什么语言网站比较安全/今天的新闻摘抄
  • 专业代做时时彩网站/优化快速排名公司
  • 深度学习TR3周:Pytorch复现Transformer
  • 【PHP】对比两张图片的相似度
  • Flutter开发 dart异步
  • C语言数据结构(7)贪吃蛇项目2.贪吃蛇项目实现
  • 电脑声音标志显示红叉的原因
  • [Linux入门] Ubuntu 系统中 iptables 的配置与使用