Locker

C#队列学习笔记:RabbitMQ使用多线程提高消费吞吐率

心已入冬 提交于 2020-04-17 02:16:10
【推荐阅读】微服务还能火多久?>>> 一、引言 使用工作队列的一个好处就是它能够并行的处理队列。如果堆积了很多任务,我们只需要添加更多的工作者(workers)就可以了,扩展很简单。本例使用多线程来创建多信道并绑定队列,达到多workers的目的。 二、示例 2.1、环境准备 在NuGet上安装RabbitMQ.Client。 2.2、工厂类 添加一个工厂类RabbitMQFactory: /// <summary> /// 多路复用技术(Multiplexing)目的:为了避免创建多个TCP而造成系统资源的浪费和超载,从而有效地利用TCP连接。 /// </summary> public static class RabbitMQFactory { private static IConnection sharedConnection; private static int ChannelCount { get ; set ; } private static readonly object _locker = new object (); public static IConnection SharedConnection { get { if (ChannelCount >= 1000 ) { if (sharedConnection != null &&

java NIO理解分析与基本使用

假装没事ソ 提交于 2020-04-05 16:41:45
我前段时间的一篇博客 java网络编程——多线程数据收发并行 总结了服务端与客户端之间的收发并行实践。原理很简单,就是针对单一客户端,服务端起两个线程分别负责read和write操作,然后线程保持阻塞等待读写执行。 事实上,这样的模式非常糟糕。因为每一个客户端在服务端需要占用两条线程,假如有1000个客户端,则需要2000+条线程。cpu需要花费大量的时间进行线程上下文切换,造成系统资源浪费。 想要缩减线程数量,先要解决阻塞问题。而NIO可以通过IO多路复用将read和write的阻塞给抹去。再配合线程池,即可实现用少量的线程支撑起上百万个客户端的连接。 什么是NIO NIO与IO多路复用 java NIO全称java non-blocking IO。字面意思即非阻塞式IO。实际上这里的非阻塞只是宏观的说法。 关于IO模式,这里引一个别人的博客,介绍了几种IO模式的区别: 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别 本博客不再赘述这些,只是想说NIO属于其中的IO复用模型。(实验室里有一本《UNIX网络编程》疫情结束回学校一定把这部分好好看看) 多路复用IO模型中,会有一个线程去不断轮询多个socket的状态,当socket有读写事件时,才来调用IO操作。因为是一个线程来管理多个socket,系统不需要建立其它线程、维护线程,只有socket就绪时

面试刷题15:synchronized底层是如何实现的?

若如初见. 提交于 2020-03-27 17:09:23
3 月,跳不动了?>>> <br />所有的同步场景都是基于锁。锁在并发编程中发挥重要作用。<br /> <br />我是李福春,我在准备面试,今天的题目是:<br /> <br /> <br /> synchronized底层是如何实现的? 答: synchronized是在底层的jvm中实现的,即c++写的,synchronized的实现是基于一对monitorenter, monitorexit指令实现的,monitor对象是同步的基本实现单元。<br /> <br />在java6中,monitor依靠操作系统提供的内部互斥锁,需要在用户态空间和内核态空间切换,所以同步操作是一个比较重的操作,开销比较大。<br /> <br />在java7之后,monitor有三种不同的实现,即偏斜锁,轻量级锁,重量级锁。<br /> <br />基于对象头的markword,标记上偏向的线程id, 在没有竞争的条件下,使用的是偏斜锁;<br />当有多个线程来竞争偏斜锁,基于cas对对象头的markword来进行竞争,如果拿到了,升级为轻量级锁。<br />没拿到则升级为重量级锁;<br /> <br />锁降级发生在jvm进入安全点检查的时候,对monitor进行降级。<br /> <br /> synchronized底层实现 <br />对象头结构:<br /> <br />

Go语言—sync.Cond源码分析

寵の児 提交于 2019-12-30 13:43:24
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 原文链接 Cond的主要作用就是获取锁之后,wait()方法会等待一个通知,来进行下一步锁释放等操作,以此控制锁合适释放,释放频率,适用于在并发环境下goroutine的等待和通知。 针对Golang 1.9的sync.Cond,与Golang 1.10一样。 源代码位置:sync\cond.go。 结构体 ` type Cond struct { noCopy noCopy // noCopy可以嵌入到结构中,在第一次使用后不可复制,使用go vet作为检测使用 // 根据需求初始化不同的锁,如*Mutex 和 *RWMutex L Locker notify notifyList // 通知列表,调用Wait()方法的goroutine会被放入list中,每次唤醒,从这里取出 checker copyChecker // 复制检查,检查cond实例是否被复制 } ` 再来看看等待队列notifyList结构体: type notifyList struct { wait uint32 notify uint32 lock uintptr head unsafe.Pointer tail unsafe.Pointer } 函数 NewCond 相当于Cond的构造函数,用于初始化Cond。

原理剖析(第 003 篇)ThreadPoolExecutor工作原理分析

瘦欲@ 提交于 2019-12-17 19:48:06
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 原理剖析(第 003 篇)ThreadPoolExecutor工作原理分析 一、大致介绍 1、相信大家都用过线程池,对该类ThreadPoolExecutor应该一点都不陌生了; 2、我们之所以要用到线程池,线程池主要用来解决线程生命周期开销问题和资源不足问题; 3、我们通过对多个任务重用线程以及控制线程池的数目可以有效防止资源不足的情况; 4、本章节就着重和大家分享分析一下JDK8的ThreadPoolExecutor核心类,看看线程池是如何工作的; 二、基本字段方法介绍 2.1 构造器 1、四个构造器: // 构造器一 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } // 构造器二 public ThreadPoolExecutor(int

nps源码阅读--自旋锁(Spinlock)

倾然丶 夕夏残阳落幕 提交于 2019-12-11 23:27:47
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 定义 自旋锁是计算机科学用于多线程同步的一种锁,线程反复检查锁变量是否可用。由于线程保持活动状态,但未执行其他的任务,因此是一种 繁忙等待(Busy waiting) 。一旦获取了自旋锁,线程会一直保持该锁,直至显式释放自旋锁。它避免了进程重新调度或上下文的切换带来的开销,因此对于线程只会阻塞很短时间的场合是有效的。 go源码 package internal import ( "runtime" "sync" "sync/atomic" ) type spinLock uint32 func (sl *spinLock) Lock() { for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) { //判断是否能获得锁 runtime.Gosched() //出让cpu } } func (sl *spinLock) Unlock() { atomic.StoreUint32((*uint32)(sl), 0) } // NewSpinLock 实例化自旋锁 func NewSpinLock() sync.Locker { return new(spinLock) } //代码来源 github.com/panjf2000/ants runtime

死磕 java同步系列之redis分布式锁进化史

ぃ、小莉子 提交于 2019-12-06 06:44:44
(手机横屏看源码更方便) 问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 本章我们将介绍如何基于redis实现分布式锁,并把其实现的进化史从头到尾讲明白,以便大家在面试的时候能讲清楚redis分布式锁的来(忽)龙(悠)去(考)脉(官)。 实现锁的条件 基于前面关于锁(分布式锁)的学习,我们知道实现锁的条件有三个: (1)状态(共享)变量,它是有状态的,这个状态的值标识了是否已经被加锁,在ReentrantLock中是通过控制state的值实现的,在ZookeeperLock中是通过控制子节点来实现的; (2)队列,它是用来存放排队的线程,在ReentrantLock中是通过AQS的队列实现的,在ZookeeperLock中是通过子节点的有序性实现的; (3)唤醒,上一个线程释放锁之后唤醒下一个等待的线程,在ReentrantLock中结合AQS的队列释放时自动唤醒下一个线程,在ZookeeperLock中是通过其监听机制来实现的;

探秘Runtime

冷暖自知 提交于 2019-12-05 03:58:55
该文章属于<简书 — 刘小壮>原创,转载请注明: <简书 — 刘小壮> https://www.jianshu.com/p/4fb2d7014e9e 程序加载过程 在iOS程序中会用到很多系统的动态库,这些动态库都是动态加载的。所有iOS程序共用一套系统动态库,在程序开始运行时才会开始链接动态库。 除了在项目设置里显式出现的动态库外,还会有一些隐式存在的动态库。例如 objc 和 Runtime 所属的 libobjc.dyld 和 libSystem.dyld ,在 libSystem 中包含常用的 libdispatch(GCD) 、 libsystem_c (C语言基础库)、 libsystem_blocks(Block) 等。 使用动态库的优点: 防止重复。iOS系统中所有 App 公用一套系统动态库,防止重复的内存占用。 减少包体积。因为系统动态库被内置到iOS系统中,所以打包时不需要把这部分代码打进去,可以减小包体积。 动态性。因为系统动态库是动态加载的,所以可以在更新系统后,将动态库换成新的动态库。 加载过程 在应用程序启动后,由 dyld(the dynamic link editor) 进行程序的初始化操作。大概流程就像下面列出的步骤,其中第3、4、5步会执行多次,在 ImageLoader 加载新的 image 进内存后就会执行一次。 在引用程序启动后,由

Windows7至Windows10的升级建议

妖精的绣舞 提交于 2019-12-01 15:46:50
目前,诸多企业或已开始在进行Windows7至Windows10的升级,或正在规划Windows7升级至Windows10。 主要原因有两个: Windows7的生命周期即将结束,这意味着再也无法获取Windows7的安全更新,以及Microsoft 客户服务将不再提供 Windows 7 的技术支持。 ​ 各PC厂商其硬件已采用新一代的AMD或Intel品牌的CPU,其对于Windows7已经无法很好地兼容。 如何将Windows7平滑升级至Windows10,升级过程中要注意哪些地方呢?笔者结合自己的理解与经验给出一些建议,希望对正在考虑进行此项工作的人员有所帮助。 一、 Windows7的生命周期说明 Microsoft 承诺为 Windows 7 提供自其 2009 年 10 月 22 日发布以来为期 10 年的产品支持。在为期 10 年的期限结束后,Microsoft 将停止为 Windows 7 提供支持,以便将精力专注于支持较新的技术和出色的新体验。对 Windows 7 的终止支持具体日期将是 2020 年 1 月 14 日。此后,微软将不再为该产品提供技术帮助和有助于保护电脑的自动更新。Microsoft 强烈建议在 2020 年 1 月之前的某个时间升级到 Windows 10,以避免无法获得所需的服务或支持。 终止支持意味着什么呢?在 2020 年 1 月

Linux简单高并发模型——Epoll + 线程池

主宰稳场 提交于 2019-11-28 18:54:56
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_25425023/article/details/70199133 首先是一个locker.h的文件,封装了信号量、互斥量、条件变量。 在线程池中的任务队列需要互斥量的保护,当任务队列中有任务到达时,需要唤醒一个等待pthread_cond_wait()的线程,线程池停止时,需要唤醒所以的线程,调用的是pthread_cond_broadcast()。 locker.h文件: #ifndef _LOCKER_H_ #define _LOCKER_H_ #include <pthread.h> #include <stdio.h> #include <semaphore.h> /*信号量的类*/ class sem_locker { private: sem_t m_sem; public: //初始化信号量 sem_locker() { if(sem_init(&m_sem, 0, 0) != 0) printf("sem init error\n"); } //销毁信号量 ~sem_locker() { sem_destroy(&m_sem); } //等待信号量 bool wait() { return sem