java中并发是什么意思排序是什么意思

java是怎么解决高并发的? - 知乎有问题,上知乎。知乎作为中文互联网最大的知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。13被浏览<strong class="NumberBoard-itemValue" title="分享邀请回答02 条评论分享收藏感谢收起1添加评论分享收藏感谢收起写回答19:26 提问
java中什么是高并发和多线程?高并发和多线程有什么关系
高并发和多线程有什么关系吗?访问量一多是不是必须要有多线程来实现?
按赞数排序
高并发不是JAVA的专有的东西,是语言无关的广义的,为提供更好互联网服务而提出的概念。
举个极端的例子,就是100个人,1人分配1台web服务器,
那么服务器资源是他们独占的,他们不需要抢占服务器资源,100个请求被100台服务器并行处理,速度必定很快,这就是高并发。
当然这是不可能的,但是,我们总是努力去做,让少量的服务器也能达到近似的能力。
这就需要服务器的HTML画面,后台业务逻辑,db数据存取等等细节上的处理都达到一个并行的极致,
以此来实现整个服务器对所有请求的高并行。这是战略上的并行。
多线程只是为了达到高并发目的,在某个细节点上,为实现某并发功能而采用的一种具体的实现方法,这种功能也可以由多进程实现,
当然,也可以由多进程,多线程一起实现。这是战术上的并行。
那么可以说,高并发是目的,多线程是某种手段(不是唯一的),高并发可以由多线程实现,但是多线程不代表就是高并发。
高并发就是同时处理很多请求。除了用多线程,还有多进程,甚至多计算机。
高并发就是可以同时处理多个。逻辑流上的同时处理。多线程就是cpu逻辑上的同时处理。对于多核CPU,可以多线程真正意义的并行
高并发的主要原理就是多线程,好比如说一百个人同时访问淘宝网。
那么淘宝网的服务器便会为这一百个人分别开一条线程为提供服务
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐让天下没有难学的技术
JVM的重排序
JVM的重排序
感谢同事【】的投稿
重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段。重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境。
在并发程序中,程序员会特别关注不同进程或线程之间的数据同步,特别是多个线程同时修改同一变量时,必须采取可靠的同步或其它措施保障数据被正确地修改,这里的一条重要原则是:不要假设指令执行的顺序,你无法预知不同线程之间的指令会以何种顺序执行。
但是在单线程程序中,通常我们容易假设指令是顺序执行的,否则可以想象程序会发生什么可怕的变化。理想的模型是:各种指令执行的顺序是唯一且有序的,这个顺序就是它们被编写在代码中的顺序,与处理器或其它因素无关,这种模型被称作,也是基于冯·诺依曼体系的模型。当然,这种假设本身是合理的,在实践中也鲜有异常发生,但事实上,没有哪个现代多处理器架构会采用这种模型,因为它是在是太低效了。而在编译优化和CPU流水线中,几乎都涉及到指令重排序。
一、编译期重排序
编译期重排序的典型就是通过调整指令顺序,在不改变程序语义的前提下,尽可能减少寄存器的读取、存储次数,充分复用寄存器的存储值。
假设第一条指令计算一个值赋给变量A并存放在寄存器中,第二条指令与A无关但需要占用寄存器(假设它将占用A所在的那个寄存器),第三条指令使用A的值且与第二条指令无关。那么如果按照顺序一致性模型,A在第一条指令执行过后被放入寄存器,在第二条指令执行时A不再存在,第三条指令执行时A重新被读入寄存器,而这个过程中,A的值没有发生变化。通常编译器都会交换第二和第三条指令的位置,这样第一条指令结束时A存在于寄存器中,接下来可以直接从寄存器中读取A的值,降低了重复读取的开销。
二、重排序对于流水线的意义
现代CPU几乎都采用流水线机制加快指令的处理速度,一般来说,一条指令需要若干个CPU时钟周期处理,而通过流水线并行执行,可以在同等的时钟周期内执行若干条指令,具体做法简单地说就是把指令分为不同的执行周期,例如读取、寻址、解析、执行等步骤,并放在不同的元件中处理,同时在执行单元EU中,功能单元被分为不同的元件,例如加法元件、乘法元件、加载元件、存储元件等,可以进一步实现不同的计算并行执行。
流水线架构决定了指令应该被并行执行,而不是在顺序化模型中所认为的那样。重排序有利于充分使用流水线,进而达到的效果。
三、确保顺序性
尽管指令在执行时并不一定按照我们所编写的顺序执行,但毋庸置疑的是,在单线程环境下,指令执行的最终效果应当与其在顺序执行下的效果一致,否则这种优化便会失去意义。
通常无论是在编译期还是运行期进行的指令重排序,都会满足上面的原则。
四、Java存储模型中的重排序
在Java存储模型(Java Memory Model, JMM)中,重排序是十分重要的一节,特别是在并发编程中。JMM通过happens-before法则保证顺序执行语义,如果想要让执行操作B的线程观察到执行操作A的线程的结果,那么A和B就必须满足happens-before原则,否则,JVM可以对它们进行任意排序以提高程序性能。
volatile关键字可以保证变量的可见性,因为对volatile的操作都在Main Memory中,而Main Memory是被所有线程所共享的,这里的代价就是牺牲了性能,无法利用寄存器或Cache,因为它们都不是全局的,无法保证可见性,可能产生脏读。
volatile还有一个作用就是局部阻止重排序的发生,对volatile变量的操作指令都不会被重排序,因为如果重排序,又可能产生可见性问题。
在保证可见性方面,锁(包括显式锁、对象锁)以及对原子变量的读写都可以确保变量的可见性。但是实现方式略有不同,例如同步锁保证得到锁时从内存里重新读入数据刷新缓存,释放锁时将数据写回内存以保数据可见,而volatile变量干脆都是读写内存。
原创文章,转载请注明: 转载自本文链接地址:
资深Java研发工程师,关注系统稳定性、性能优化、Web系统架构。
Latest posts by 王 晨纯 ()
Related posts:
(2 votes, average: 3.00 out of 5)
Loading...新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
稍有积蓄, 积分 284, 距离下一级还需 216 积分
论坛徽章:1
获奖详情:
& && &现在Java和微软的.Net两大平台对垒,各有所长,长时间内会持续共存。虽然Java运行速度慢,但其跨平台特性使得围绕着JVM语言依然一片生机。现在计算机速度越来越快,JVM的设计本身也不断借鉴其它语言使得其速度与早期有大大提高。现在并发编程越来越重要,Java相比其它语言,在语言层次对并发编程的提供了更加友好的支持,这就大大减轻了并发编程过中的设计成分,这也为Java语言提供了 更强的竞争力。在你工作过程中,结合实际,讨论以下问题:
讨论话题:
1:在你工作中是否有并发编程经历?简述一下。
2:你对并发编程是如何理解的?简述你所知道的并发编程的实现方式.
3:并发编程对语言层次提出了什么样的要求?比如对内存模型设计有什么要求,对语言架构设计有什么要求.
4:如果让你设计并发编程的一个实现方式,简述一下你的思路。
5:如果让你想象,并发编程的下一代编程方式会是什么样子呢?
讨论时间:
活动奖励:
活动结束后将选取5名讨论精彩的童鞋,每人赠送一本《Java并发编程的艺术》作为奖励。
奖品简介:
作者:&&方腾飞、魏鹏程、晓明
丛书名:Java核心技术系列
出版社:机械工业出版社
上架时间:
出版日期:2015 年7月
开本:16开
内容简介:
并发编程领域的扛鼎之作,作者是阿里和1号店的资深Java技术专家,对并发编程有非常深入的研究,本书是他们多年一线开发经验的结晶。本书的部分内容在出版早期发表在Java并发编程网和帅foQ等技术社区,得到了非常高的评价。它选取了Java并发编程中最核心的技术进行讲解,从JDK源码、JVM、CPU等多角度全面剖析和讲解了Java并发编程的框架、工具、原理和方法,对Java并发编程进行了最为深入和透彻的阐述。
&&内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时通过实例介绍了如何应用这些技术。
试读样章:
(742.81 KB, 下载次数: 50)
10:46 上传
点击文件名下载附件
(3.33 MB, 下载次数: 249)
10:46 上传
点击文件名下载附件
小富即安, 积分 2547, 距离下一级还需 2453 积分
论坛徽章:16
人气很低,这是一本好书,大家快来参与。
丰衣足食, 积分 765, 距离下一级还需 235 积分
论坛徽章:13
本帖最后由 chenxing2 于
16:00 编辑
1:在你工作中是否有并发编程经历?简述一下。
& &并发编程通常少不了线程,线程两种实现方式也是多线程的基础。
& &使用第三方推送时,使用生产者消费者模式,并限制推送量及时间。
& &用NETTY实现内部聊天系统,有时间使用这个做推送功能抛开第三方。
2:你对并发编程是如何理解的?简述你所知道的并发编程的实现方式.
& &并发编程,最开始是最大化利用单机资源。
& &并发编程的方式:
& &BIO,传统的并发编程方式,缺乏弹性,服务器端的线程与客户端连接数一致,线程数膨胀代理系统性能下降,
& && &&&最后,栈溢出、线程创建失败、直到程序崩掉。现在很少用了。
& &NIO,JDK1.4引入,1.7带来了NIO2.0,目前主流方式,代表框架mina/netty。基于事件驱动方式解决BIO的
& && &&&大并发问题。
& &AIO,JDK1.7引入的,目前不是主流。性能貌似不如NIO,但适合大文件的编写。
& && &&&从AIO的发展来看,从03年的Linux Kernel 2.4到IBM再到ORACLE 07年Oracle尝试用
& & & & & & & & syslet方案实现新的AIO,也没有了下文,目前这个AIO还待观察。
& & & & & & & &
& &也有基于Actor模型的并发编程方式,如AKKA
& && & 基于ringbuffer模型的Disruptor等等
3:并发编程对语言层次提出了什么样的要求?比如对内存模型设计有什么要求,对语言架构设计有什么要求.
& &在多核系统中,处理器一般有一层或者多层的缓存,这些的缓存通过加速数据访问和降低共享内存在总线
上的通讯来提高CPU性能,并发编程对语言层次的要求,首先要充分利用这个缓存来大大的提高性能;其次要
能正确的使用缓存中的值,因为需要保证多个线程任何时候访问某个内存地址时,要能看到完全相同的值。
& &对于C/C++等语言则没有内存模型,他们对于发生在编译器和处理器平台架构的重排序行为的保护机制依赖于
程序中所使用的线程库、编译器、以及代码所运行的平台提供的保障。
& &对于java等存在内存模型的语言来说
& &在弱内存模型下,通常需要使用内存屏障(CPU指令)来处理缓存-&使缓存无效,就为了让处理器看到缓存
最新的值,如volatile关键字
& &在强内存模型下,就减少了对内存屏障的依赖,性能也会提高,毕竟内存屏障通常在锁模式下完成。
& &目前来看更偏向于弱内存模型,因为该模型在多处理器平台或更大内存下可以实现更好的可伸缩性。
4:如果让你设计并发编程的一个实现方式,简述一下你的思路。
& &这个个人能力达不到,还是使用成熟框架吧,如NETTY、AKKA之类的。
5:如果让你想象,并发编程的下一代编程方式会是什么样子呢?
& &目前来看并发编程,难度比较高,很容易出现各种各样的问题。
& &下一代的编程方式,应该易用,而又不失并发的性能。
论坛徽章:138
shenlanyouyu总是这么给力 回复
shenlanyouyu
家境小康, 积分 1299, 距离下一级还需 701 积分
论坛徽章:30
本帖最后由 jieforest 于
16:03 编辑
1:在你工作中是否有并发编程经历?简述一下。
这是常事了,这么多年来,时不时就会写一些多线程的开发。我在这方面的历程大致是这样的:
最早是直接用Java线程类(或继承Runnable)实现多线程程序,以达到并发的效果。
接着是自己实现了线程池,减少线程的创建及销毁的开销,对线程提供了基本的管理,实现了线程的复用。
再后来是利用Java 7引入的Fork/Join框架开发。
再后来是使用Akka库开发高并发、高性能的程序。
目前也在尝试逐步使用GoLang开发一些高并发的程序。
2:你对并发编程是如何理解的?简述你所知道的并发编程的实现方式。
请参考第一问的答案。
3:并发编程对语言层次提出了什么样的要求?比如对内存模型设计有什么要求,对语言架构设计有什么要求。
Java线程间的通信有两类:一是共享内存的方式;二是消息传递的方式。
Java线程间的通信是由Java内存模型所控制的,它决定了一线程的共享变量是否对另一线程可见。
每个线程都有自己的本地内存,本地内存存储了读写共享变量的副本,而共享变量存放于主内存中。
缓冲区技术得到广泛应用,处理器会使用写缓冲区临时保存向内存写入的数据,写缓冲区可以保证指令流水线持续运行,避免延迟,并减少内存总线的占用。但是处理器的写缓冲区仅对它所在的处理器可见,会导致处理器执行内存操作的顺序可能会与内存实际的操作执行顺序不一致。因此目前的多核处理器允许对写-读操作进行重排序。
为了保证内存可见性,Java编译器在生成指令序列的适当位置会插入内存屏障指令来禁止特定类型的处理器重排序。
Java的内存屏障类型有:LoadLoad Barriers、StoreStore Barriers、LoadStore Barriers、StoreLoad Barriers。
重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。无论怎样重排序,编译器、运行时和处理器都必须遵守as-if-serial语义。
在设计时,处理器的内存模型和编程语言的内存模型都会以顺序一致性内存模型作为参照。顺序一致性内存模型是一个理想的理论参考模型,它为程序员提供了极强的内存可见性保证。
4:如果让你设计并发编程的一个实现方式,简述一下你的思路。
没明白LZ的意图。说的是语言内部的并发实现方式呢?还是说业务应用的并发实现方式?
如果是前者,要设计好内存模型,让内存模型简单、易懂。其次就是&#137;&#137;编译器和处理器对内存模型的实现,让内存模型对编译器和处理器的约束越少越好,这样就能做尽可能多的优化来提高性能。
如果是后者,用好我在第一问中提到的那些技术,都可以搞定需求。
5:如果让你想象,并发编程的下一代编程方式会是什么样子呢?
并发/并行编程领域在理论方面这几年实际上没有取得什么进步。即使是比较火的技术,如Akka/Scala、Erlang,它们背后使用的是Actor模型,而Actor模型是Carl Hewitt在1973年提出的一个分布式并发编程模型,后来首先在Erlang/OPT中得到实现并加以应用、推广。
多核设计对并发编程领域能产生很大的影响,新的指令流水线方式,新的CPU架构,都可能影响到并发编程。
可用积分 +24
论坛徽章:138
期待精彩回复 回复
富甲一方, 积分 45648, 距离下一级还需 4352 积分
论坛徽章:208
王楠w_n 发表于
shenlanyouyu总是这么给力 回复 2# shenlanyouyu
小富即安, 积分 2547, 距离下一级还需 2453 积分
论坛徽章:16
这段时间比较水,马上就要忙了。
小富即安, 积分 2547, 距离下一级还需 2453 积分
论坛徽章:16
&&哈哈,我一向很给力,最近一段时间没目标漫游,所以比较闲。等一段时间就很忙了。
小富即安, 积分 2202, 距离下一级还需 2798 积分
论坛徽章:15
1:在你工作中是否有并发编程经历?简述一下。
& &&&在CPU还不是多核的时候就接触过并发编程,主要思想是状态机的方式实现,就是内部维护一个状态表,接收消息查询状态表调用对应的回调函数处理,处理完成后同时进行状态变迁,那时候程序是以多进程方式,一般是按照业务分层模式分多个进程,如业务处理进程,数据库处理进程等,每一个进程根据情况决定是否有状态机
2:你对并发编程是如何理解的?简述你所知道的并发编程的实现方式.
& &&&并发就是如何更大化的使用CPU资源,同一时间段内处理的任务越多越好,并发的实现主要有:状态机、多线程并发、actor模型等
3:并发编程对语言层次提出了什么样的要求?比如对内存模型设计有什么要求,对语言架构设计有什么要求.
& &&&语言层次能提供更好,主要是对象不可修改更利于并发,此外资源不共享并发更有利,如内存分开或公共只读
4:如果让你设计并发编程的一个实现方式,简述一下你的思路。
& &&&没到这个层次,只能用现有的方案
5:如果让你想象,并发编程的下一代编程方式会是什么样子呢?
& &&&我想大约就是scala actor之类的吧
可用积分 +12
北京盛拓优讯信息技术有限公司. 版权所有 京ICP备号 北京市公安局海淀分局网监中心备案编号:22
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处赞助商链接
Java中使用TreeSet作为排序队列或Buffer,而ConcurrentSkipListSet是支持并发的队列,如果我们需要一个能实时排序又支持并发的队列或Buffer怎么办?设想一个场景,当我们不断加入元素到集合,等所有元素都加入完毕后,我们只需要获得排序的前5个元素,比如我们对半年内所有帖子或文章根据点赞量获得前五篇点赞量最多的文章,首先我们需要将半年所有文章加入一个集合,这个集合是根据点赞量排序的,添加完毕后,我们需要获得排名前5篇文章。这可以通过JDK提供的 NavigableSet实现:NavigableSet&#60;Integer&#62; aSet = new TreeSet&#60;&#62;();
aSet.add(5);
//..add more elements
aSet.pollFirst();//'0'th
aSet.pollFirst();//'1'th
aSet = aSet.descendingSet();
aSet.pollFirst();//'n'th
aSet.pollFirst();//'n-1'th但是这种集合是无界的,它需要保留所有元素,其实有时这是没有必要的,因为我们只感兴趣所有元素中子集的子集,也就是说没有必要从数据库中获得所有结果。有没有更好的数据结构能实现有界而且像以前能够排序呢?实际是某种BoundedNavigableSet. 而且需要支持并发访问,多个生产者可以同时将元素放入其中。这种数据结构能够在分布式查询聚合实现中非常方便,特别是对分布式key-value数据库如Cassandra, 基于多个分区查询获得的结果需要收集融合在一起。下面是使用AtomicReferenceArray实现的无锁算法插入:/*Scan the array from given offset to 'insert' the itemat a proper sort level*/boolean addItem(int fromOffset, T item){
for (int i = fromO i &#60; size(); i++)
// if there is no element at 'i'th position
// set item at 'i'
if (!buffer.compareAndSet(i, null, item))
// compare and swap using Comparator provided
// or, if element implements Comparable
T swapped = compareAndSwap(i, item);
if (swapped != null)
// the item has been placed. so break. but then
// the element currently at 'i' has been swapped. so find its new
// position, if present
// we could have scanned from the 'i+1'th position, but to be safe
// just in case some other element higher up was removed and this
// needs to go up in that case
if (i + 1 &#60; size()) {
addItem(0, swapped);
return true;
return true;
}Compare 和 swap也是一个原子操作:private T compareAndSwap(int i, T item)
boolean set = false, greater =
T t = null;
while (!set) {
t = buffer.get(i);
// either i-th element was replaced with this item
// or by some other element
// compare using Comparator/Comparable
greater = compare(item, t) &#62; 0;
set = buffer.compareAndSet(i, t, greater ? item : t);
return greater ? t : null;
}removal操作也应该是原子的:public boolean remove(Object o) {
if(o == null)
for (int i = 0; i &#60; size(); i++) {
b = buffer.get(i);
if (o.equals(b))
if(buffer.compareAndSet(i, b, null))
//shift left elements
for (int j = i + j &#60; size(); j++) {
//check position form start. it can be possible that another higher item has been removed in the meantime
addItem(0, buffer.get(j));
return true;
}完整源码见:[该贴被banq于 11:25修改过]
赞助商链接
赞助商链接
最佳分辨率
OpenSource
Code & 2002-20

我要回帖

更多关于 java多线程与高并发 的文章

 

随机推荐