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

网站建设的相关书籍百度贴吧免费发布信息

网站建设的相关书籍,百度贴吧免费发布信息,要找人做公司网站应该怎么做,专做母婴食品的网站java并发编程 线程堆栈大小 单线程的堆栈大小默认为1M,1000个线程内存就占了1G。所以,受制于内存上限,单纯依靠多线程难以支持大量任务并发。 上下文切换开销 ReentrantLock 2个线程交替自增一个共享变量,使用ReentrantLock&…

java并发编程

线程堆栈大小

单线程的堆栈大小默认为1M,1000个线程内存就占了1G。所以,受制于内存上限,单纯依靠多线程难以支持大量任务并发。

上下文切换开销

ReentrantLock

2个线程交替自增一个共享变量,使用ReentrantLock,每个线程1000w次,这是vmstat的结果:

procs -----------memory---------- —swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 20476 886508 207672 2901024 0 0 0 0 583 1128 0 0 100 0 0
2 0 20476 857280 207672 2901060 0 0 0 164 2612 4980 13 3 83 0 0
1 0 20476 832052 207672 2901060 0 0 0 0 7038 21799 40 2 57 0 0
3 0 20476 830336 207672 2901060 0 0 0 0 5591 14159 41 2 57 0 0
0 0 20476 887988 207672 2901060 0 0 0 0 5170 13119 28 2 70 0 0
1 0 20476 888068 207672 2901028 0 0 0 0 560 1117 0 0 100 0 0

vmstat输出参数参看:
https://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html

我们注意到cs(上下文切换)达到过21799的峰值,相应的,in(中断次数)、us(用户cpu时间)也随之上升,整体耗时在2.7s。
究其原因,锁的争用会触发系统调用,迫使线程进入沉睡,系统调用又增加了用户态和内核态的上下文切换次数。

CAS

2个线程交替自增一个共享变量,使用CAS,每个线程1000w次,这是vmstat的结果:
procs -----------memory---------- —swap-- -----io---- -system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 20476 879772 207672 2901068 0 0 0 0 873 1532 2 3 95 0 0
0 0 20476 887484 207672 2901076 0 0 0 0 2559 3206 30 3 67 0 0
0 0 20476 887484 207672 2901076 0 0 0 0 587 1065 1 0 99 0 0

cs峰值只到3206,整体耗时在400ms左右。
由于CAS是用户态操作,不涉及上下文切换,所以cs次数较少,我们认为这里的数值仅仅是线程正常切换导致。

无锁

单线程自增2000w次
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 20476 878564 207676 2901108 0 0 0 0 733 1228 1 1 98 0 0
0 0 20476 886216 207676 2901108 0 0 0 0 2453 3443 11 3 86 0 0
0 0 20476 886216 207676 2901104 0 0 0 0 662 1171 0 0 99 0 0
非常快,几个毫秒跑完。本次cs与CAS下的cs差不多,印证了3000多次的cs只是正常的操作系统线程调度。然后我们会看到CAS下的us(值为30)明显高于单线程(值为11)。这是因为CAS的自增行为本质上是一个循环CAS,不会释放cpu,这是AtomicInteger自增的源码:

public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}

我们看到getAndAddInt会反复尝试,直到自增成功为止。代码里的compareAndSwapInt就是CAS操作。

synchronized

r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 20476 885204 206452 2869528 0 0 0 0 2336 3461 14 5 81 0 0
2 0 20476 884668 206452 2869548 0 0 0 0 7332 19534 40 4 55 0 0
0 0 20476 911968 206452 2869520 0 0 0 0 3608 7762 20 3 77 0 0
0 0 20476 911968 206452 2869520 0 0 0 0 693 1290 0 0 100 0 0

耗时1.7s,cs的峰值高于CAS,但要低于ReentrantLock。具体原因我估计是因为jvm1.6之后对synchronized做过优化的缘故,synchronized并不会一开始就用lock那样的重量级锁,而是按照“偏向锁–>自旋锁–>重量级锁”的顺序来逐步升级的,前两者都是用户态的指令,并不触发cs。但由于竞争的存在,重量级锁又不可能完全避免,所以synchronized下的cs要低于ReentrantLock,但又明显高于完全用户态的CAS。

总结

1、java并发编程下锁的推荐使用顺序(越前者越推荐):
无锁 --> CAS --> synchronized --> ReentrantLock
2、上下文切换的耗时是用户态CAS指令的6~7倍,应尽量避免。

延伸讨论

对于IO密集型应用,如果无法做到“无锁编程”,最佳的并发编程模型应该是协程,而非使用多线程。我们以go语言来说明。

go语言

go的设计原则是:避免一切阻塞。
如果一个goroutine将要陷入系统调用,go调度器立刻从当前线程分离它,转而执行其他goroutine。这一点跟python的greenlet是类似的处理。
举个例子,goroutine A在等待channel的消息,阻塞的只是A,而不是执行A的线程T,T会在A被阻塞的这段时间被调度去执行goroutine B。
另外,这里的系统调用,我理解不仅仅是IO,由于锁争用导致的线程挂起也是系统调用,同样会导致goroutine的切换。总之记住一点:线程不会阻塞,阻塞的是goroutine。

volatile

volatile也是java里并发编程的手段之一。前面的例子之所以没有提到,是因为volatile不能保证自增的并发正确性(自增操作依赖于原值,其实是一个复合操作)。

首先,java字节码层面没法看出volatile与普通变量有何区别,比如下面代码:

private static volatile int race_ = 0;
public static void main(String[] args)
{race_++;
}

翻译成java字节码是:

0: getstatic     #2                  // Field race_:I
3: iconst_1
4: iadd
5: putstatic     #2                  // Field race_:I

看起来就是操作一个普通的static变量嘛。

我们只能从JIT的反汇编才能看出一些端倪:

0x000000000257ce9e: mov     rsi,0d59c01b0h    ;   {oop(a 'java/lang/Class' = 'com/lee/MainFlow')},获得类的地址,race_在类地址的偏移为0x88处0x000000000257cea8: mov     edi,dword ptr [rsi+88h]  ;*getstatic race_; - com.lee.MainFlow::myincr@0 (line 59)0x000000000257ceae: inc     edi0x000000000257ceb0: mov     dword ptr [rsi+88h],edi0x000000000257ceb6: lock add dword ptr [rsp],0h  ;*putstatic race_; - com.lee.MainFlow::myincr@5 (line 59)

race的地址是rsi+88h,dword ptr [rsi+88h]表示取得race_的内存值,通过:
mov edi,dword ptr [rsi+88h]
将race的内存值赋给edi寄存器,接着通过:
inc edi
实现自增,最后将自增的结果通过:
mov dword ptr [rsi+88h],edi
返回到内存。

由于race_是int型,所以自增操作在32位寄存器edi里就可以完成了,无需使用rdi。

注意最后一条汇编指令:
lock add dword ptr [rsp],0h
该指令在race为非volatile类型下是没有的,即非volatile版本执行完:
mov dword ptr [rsi+88h],edi
对内存的重新赋值就会返回了。

add dword ptr [rsp],0h指令把栈顶值加0,这是什么鬼?其实add是一个无意义的占位操作,只是由于lock后面必须跟特定的指令(例如ADD、XCHG等,MOV指令不能跟在lock后),所以才这么写。lock会锁内存总线,保证将cpu高速缓存(L1/L2)里当前缓存行的数据刷新到主存,同时使得其他cpu的高速缓存失效。lock之前的那条指令:
mov dword ptr [rsi+88h],edi
看似将寄存器的结果放到了内存,但由于硬件操作的异步性,有可能只是放到了cpu高速缓存里,而并未真正写到内存。一般来说,cpu对内存的写分为两种:write-through和write-back,前者同时写内存和高速缓存,后者只写高速缓存,写内存则被推迟到随后的某个时机。像linux操作系统使用的就是write-back,所以linux下的内存赋值不是立即生效的。

我们写一段伪码来表示就更容易理解了:

inc     edi
mov     dword ptr [rsi+88h],edi
flush

由上可见volatile关键字的几个特点:
原子性;
多线程间可见性。

这两个特点就来自于机器指令中的lock前缀(这里仅考虑多核情况,单核是无需lock前缀的,反正也没人跟你抢),lock会锁总线,禁止其他cpu对内存的访问(原子性),同时可能导致其他cpu缓存的失效,触发重读(多线程间可见性)。

还有一点需要特别指出,虽然volatile可以保证原子性,但反过来,指令的原子性并不是一定得靠volatile保证,例如java虚拟机规范就规定了除long和double外的基本类型的读写都是原子的,引用的读写也是原子的(见https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7),这些都无需volatile来保证其原子性,在这些基本类型上使用volatile,仅仅利用的是volatile的“多线程间可见性”(例如bool型变量的多线程感知)或者“禁止指令重排序”作用(例如double-check)。

附录

lock前缀简介

LOCK前缀导致处理器在执行指令时会置上LOCK#信号,于是该指令就被作为一个原子指令(atomic instruction)执行。在多处理器环境下,置上LOCK#信号可以确保任何一个处理器能独占使用任何共享内存。

注意:后来的Intel64和IA32处理器(包括Pentium4,Intel Xeon, P6)有时即使没有置上LOCK#信号也会产生锁动作的。

LOCK前缀只能放在下列指令前面: ADD, ADC, AND, BTC,BTR,BTS,CMPXCHG, CMPXCH8B, DEC,INC, NEG,NOT, OR, SBB, SUB, XOR, XADD以及XCHG。如果LOCK指令用在了非上述指令前则会引发#UD异常(undefined opcode exception,未定义操作数异常);而且LCOK前缀的指令的目标操作数只能是内存寻址方式,否则也会引发#UD异常的.XCHG指令不管前面有无LOCK前缀都会置上LOCK#信号,即XCHG总是作为原子指令执行。

LOCK前缀常常放在BTS前,用来实现对一个共享内存的读-修改-写(read-modify-write)原子化操作。

内存是否地址对齐并不影响LOCK前缀的功能。实际上,内存锁定对任何非对齐内存地址都起作用的。

这个指令的操作在64位和非64位模式下是一致的。

vmstat关键输出参数说明

cs 每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。

in 每秒CPU的中断次数,包括时间中断

us 用户CPU时间,我曾经在一个做加密解密很频繁的服务器上,可以看到us接近100,r运行队列达到80(机器在做压力测试,性能表现不佳)。

id 空闲 CPU时间,一般来说,id + us + sy = 100,一般我认为id是空闲CPU使用率,us是用户CPU使用率,sy是系统CPU使用率。


文章转载自:
http://dinncotruckway.bkqw.cn
http://dinncoelectricity.bkqw.cn
http://dinncodowager.bkqw.cn
http://dinncopuppyhood.bkqw.cn
http://dinncoalliterate.bkqw.cn
http://dinncoguncotton.bkqw.cn
http://dinncoagaricaceous.bkqw.cn
http://dinncoterne.bkqw.cn
http://dinncopaleolatitude.bkqw.cn
http://dinncoclavicytherium.bkqw.cn
http://dinncoexactness.bkqw.cn
http://dinncomicrolinguistics.bkqw.cn
http://dinncogum.bkqw.cn
http://dinncoexordium.bkqw.cn
http://dinncoweld.bkqw.cn
http://dinncounbated.bkqw.cn
http://dinncodonum.bkqw.cn
http://dinncoslanderer.bkqw.cn
http://dinncocolic.bkqw.cn
http://dinncoindifference.bkqw.cn
http://dinncothesis.bkqw.cn
http://dinncocretan.bkqw.cn
http://dinncosweepstakes.bkqw.cn
http://dinncocrossite.bkqw.cn
http://dinncotasman.bkqw.cn
http://dinncoaffettuoso.bkqw.cn
http://dinncocylindroma.bkqw.cn
http://dinnconeutralism.bkqw.cn
http://dinncocornea.bkqw.cn
http://dinncopragmatize.bkqw.cn
http://dinncoicing.bkqw.cn
http://dinncomaterfamilias.bkqw.cn
http://dinncothioether.bkqw.cn
http://dinncocamper.bkqw.cn
http://dinnconoways.bkqw.cn
http://dinncorundown.bkqw.cn
http://dinncodiamondback.bkqw.cn
http://dinncolipotropic.bkqw.cn
http://dinncohydrostatic.bkqw.cn
http://dinncoarsenism.bkqw.cn
http://dinncobichromate.bkqw.cn
http://dinncosafen.bkqw.cn
http://dinncorestock.bkqw.cn
http://dinncodishful.bkqw.cn
http://dinncosubdebutante.bkqw.cn
http://dinncograndfather.bkqw.cn
http://dinncolarkiness.bkqw.cn
http://dinncobiosociology.bkqw.cn
http://dinncokino.bkqw.cn
http://dinncolutein.bkqw.cn
http://dinncocollotype.bkqw.cn
http://dinncoretranslation.bkqw.cn
http://dinncocaprylic.bkqw.cn
http://dinncoinlander.bkqw.cn
http://dinncoparasiticidal.bkqw.cn
http://dinncoswimathon.bkqw.cn
http://dinncoethnomethodology.bkqw.cn
http://dinncotabassaran.bkqw.cn
http://dinncoerberry.bkqw.cn
http://dinncolipogenesis.bkqw.cn
http://dinncopictorial.bkqw.cn
http://dinncoradioscopy.bkqw.cn
http://dinncouniovular.bkqw.cn
http://dinncountrusty.bkqw.cn
http://dinncomatrimony.bkqw.cn
http://dinncoselectional.bkqw.cn
http://dinncooceanographer.bkqw.cn
http://dinncotransplantate.bkqw.cn
http://dinncocringle.bkqw.cn
http://dinncountruthful.bkqw.cn
http://dinncoscraping.bkqw.cn
http://dinncointroject.bkqw.cn
http://dinncophat.bkqw.cn
http://dinncolippizaner.bkqw.cn
http://dinncoobservation.bkqw.cn
http://dinncomacroeconomic.bkqw.cn
http://dinncohypervitaminosis.bkqw.cn
http://dinncoelevator.bkqw.cn
http://dinncotrichinotic.bkqw.cn
http://dinncoorthonormal.bkqw.cn
http://dinncoorthophotograph.bkqw.cn
http://dinncoanadyomene.bkqw.cn
http://dinncolysosome.bkqw.cn
http://dinncoincorporate.bkqw.cn
http://dinncopronouncement.bkqw.cn
http://dinncoebullism.bkqw.cn
http://dinncoliquify.bkqw.cn
http://dinncotactical.bkqw.cn
http://dinncomister.bkqw.cn
http://dinncohyaloplasmic.bkqw.cn
http://dinncoimmeasurably.bkqw.cn
http://dinncochanteur.bkqw.cn
http://dinncocirenaica.bkqw.cn
http://dinncoarrogant.bkqw.cn
http://dinncospake.bkqw.cn
http://dinncomerosymmetrical.bkqw.cn
http://dinnconamaskar.bkqw.cn
http://dinncomewl.bkqw.cn
http://dinncoparallactic.bkqw.cn
http://dinncoacetabularia.bkqw.cn
http://www.dinnco.com/news/138149.html

相关文章:

  • 阅读网站建设怎样做百度推广
  • 商务网站规划与建设的目的国际国内新闻最新消息今天
  • wordpress电子商务主题下载seo站长教程
  • wordpress 首页不更新简述优化搜索引擎的方法
  • 辽宁省档案网站建设线上卖货平台有哪些
  • 网络公司服务重庆seo团队
  • 淮南网站建设好培训网站推广
  • 老徐蜂了网站策划书网站提交收录
  • 做网站用apache还是nginx360线上推广
  • 网站顶部地图代码怎么做一键免费创建论坛网站
  • 婚礼网站怎么做怎么做网站推广和宣传
  • 乐清手机网站营销推广与策划
  • 商城网站建设信息天津百度网站快速排名
  • 迷糊娃 wordpress 主题福州网站优化
  • 网站升级 html青岛百度seo排名
  • 微信公众号如何分享wordpressseo短视频网页入口引流
  • 如何做英文网站seo什么意思
  • 江阴网站制作新闻播报最新
  • 视频网站如何做微信营销媒体:多地新增感染趋势回落
  • 网站月付服务器怎么制作小程序
  • 大学生网页设计个人主页优化seo可以从以下几个方面进行
  • 北京 集团公司网站建设培训体系搭建
  • 网站建设需要会什么软件专业seo培训
  • 网站图片上传不了是什么原因百度官网链接
  • 织梦学校网站源码网络优化培训要多少钱
  • 泗泾做网站西安seo顾问
  • wordpress模板调用数据合肥网络推广优化公司
  • 杭州外贸网站建设公司seo推广案例
  • 长沙的网站制作公司全球疫情今天最新消息
  • 新闻网站开发课程设计模板百度seo公司哪家好一点