有会Java高高度近视有哪些并发症的大神吗

21:55 提问
向大神们请教个问题,Servlet高并发
在Servlet高并发运行时,往request中存入值和取值时会出现空值,怎么解决。急急急!望大神们指点下
按赞数排序
request是对应于你servlet所产生的thread的。所以绝对是独立的。不会是因为你的高并发,而产生bug的问题。
所以你不用思考是不是高并发引起的,而应该去看下程序上是否存在bug。或者作用域的问题。
Request 保存的键值仅在下一个request对象中可以得到。
Session 它是一个会话范围,相当于一个局部变量,从Session第一次创建知道关闭,数据都一直 保存,每一个客户都有一个Session,所以它可以被客户一直访问,只要Session没有关闭和超时即浏览器关闭。
servletContext 它代表了servlet环境的上下文,相当于一个全局变量,即只要某个web应用在启动中,这个对象就一直都有效的存在,所以它的范围是最大的,存储的数据可以被所有用户使用,只要服务器不关闭,数据就会一直都存在。
你好,只要参数传递不为空,高并发是不会导致request取值为空的情况,可以排查下请求的参数值是否输入了
应该是存入request的值有问题,是不是存入的值是共享资源
编程要学会调试啊debug,看哪里出错了。
----------------------同志你好,我是CSDN问答机器人小N,奉组织之命为你提供参考答案,编程尚未成功,同志仍需努力!
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐面试Java开发时问到高并发怎么处理的,还有sql优化有哪些办法,有哪位大神知道啊,新手!!_百度知道
面试Java开发时问到高并发怎么处理的,还有sql优化有哪些办法,有哪位大神知道啊,新手!!
我有更好的答案
你好:我们公司解决高并发是用的消息并列来实现的!sql优化~比如查询几个字段就写几个字段避免使用*
不是这么简单回答吧,多说点啊
有些处理高并发的技术跟软件,比如apache整合两个timcat还有每秒1000多的用户访问才用分布式,数据库才用大型数据库,比如oracle类的。你可以百度搜一下并发处理书籍!
恩,希望能帮到你,如果满意就给个好评呗,我都辛辛苦苦给你打这么多字了!
采纳率:55%
来自团队:
高并发不是一局两句就能说清楚的- - 他通过
模式 模型 方式 和架构
高并发处理方法:1 同步处理 2 异步处理sql优化这个就有点多了,比如尽量避免null字段了,避免脏数据以及数据结构,这个很多的
Java开发高并发的处理方法:最基础的地方做起,优化我们写的代码,减少必要的资源浪费避免频繁的使用new对象,对于整个应用只需要存在一个实例的类,我们可以使用单例模式。对于String连接操作,使用&&&&&&StringBuffer或StringBuilder,对于工具类可以通过静态方法来访问。避免使用错误的方式,尽量不用instanceof做条件判断。使用java中效率高的类,比如ArrayList比Vector性能好。图片服务器分离对于web服务器来说,图片是最消耗资源的,于是我们有必要把图片与页面进行分离,我们把图片放到独立的图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片的问题而崩溃。在图片服务器上,我们可以对不同的配置进行优化。缓存具体接触过的缓存机制是hibernate的缓存机制。为了避免每次都向数据库中取得数据,我们把用户常常访问到的数据放到内存中,甚至缓存十分大的时候我们可以把内存中的缓存放到硬盘中。还有高级的分布式缓存数据库使用,都可以增加系统的抗压力。分批传送在做某项目的时候,一次传递的参数太多,而且数据库规定一次最多传递的参数最多是三万条,当时有五万条记录,那怎么传送呢?最终是分批传送,电梯里一次乘不下那么多的人,会报超重的bug,那就分批把人送上去。还有一次在考试系统中,如果那么多的考试人员同时提交到数据库中,数据库的压力增大,有时会被down掉,当时采用的方法是使用ajax异步传输,没有等待考生点击提交按钮的时候,就把考生的答案自动提交,这样也避免了突然断电考生前面做过的题出现丢失的现象。DB优化在数据库设计的时候就要考虑到后期的维护,数据库三范式是我们设计数据库索要遵循的原则。索引的建立:建立索引要适当,如果一个表经常用来被查询,对于增加和修改很少被用到,我们就可以为这个表建立索引,因为对于增加和修改和删除操作时,我们对索引的维护要大大超过索引给我们带来的效率。表字段的类型选择要恰当。包括字段的长度、类型等,要根据实际存储的数据进行选择,长度不要过长,否则会影响效率。外键要慎用,因为主键代表这一张表,而外键代表一群表,对表之间进行了关联,在删除修改等需要我们关联。在数据库操作上。 尽量使用prepareStatement,少用Statement,因为PrepareStatement是进行预编译的。connection设置为readOnly,Connection是对书库连接,属于重量级,我们使用即可。连接池的使用,我们可以修改数据库默认的连接数。
其他1条回答
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。高并发Java(4):无锁 - ImportNew
在中已经提到了无锁的概念,由于在jdk源码中有大量的无锁应用,所以在这里介绍下无锁。
1 无锁类的原理详解
CAS算法的过程是这样:它包含3个参数CAS(V,E,N)。V表示要更新的变量,E表示预期值,N表示新值。仅当V
值等于E值时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么
都不做。最后,CAS返回当前V的真实值。CAS操作是抱着乐观的态度进行的,它总是认为自己可以成功完成
操作。当多个线程同时使用CAS操作一个变量时,只有一个会胜出,并成功更新,其余均会失败。失败的线程
不会被挂起,仅是被告知失败,并且允许再次尝试,当然也允许失败的线程放弃操作。基于这样的原理,CAS
操作即时没有锁,也可以发现其他线程对当前线程的干扰,并进行恰当的处理。
我们会发现,CAS的步骤太多,有没有可能在判断V和E相同后,正要赋值时,切换了线程,更改了值。造成了数据不一致呢?
事实上,这个担心是多余的。CAS整一个操作过程是一个原子操作,它是由一条CPU指令完成的。
1.2 CPU指令
CAS的CPU指令是cmpxchg
指令代码如下:
accumulator = AL, AX, or EAX, depending on whether
a byte, word, or doubleword comparison is being performed
if(accumulator == Destination) {
Destination = S
accumulator = D
目标值和寄存器里的值相等的话,就设置一个跳转标志,并且把原始数据设到目标里面去。如果不等的话,就不设置跳转标志了。
Java当中提供了很多无锁类,下面来介绍下无锁类。
2 无所类的使用
我们已经知道,无锁比阻塞效率要高得多。我们来看看Java是如何实现这些无锁类的。
2.1. AtomicInteger
AtomicInteger和Integer一样,都继承与Number类
public class AtomicInteger extends Number implements java.io.Serializable
AtomicInteger里面有很多CAS操作,典型的有:
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
这里来解释一下unsafe.compareAndSwapInt方法,他的意思是,对于this这个类上的偏移量为valueOffset的变量值如果与期望值expect相同,那么把这个变量的值设为update。
其实偏移量为valueOffset的变量就是value
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField(&value&));
} catch (Exception ex) { throw new Error(ex); }
我们此前说过,CAS是有可能会失败的,但是失败的代价是很小的,所以一般的实现都是在一个无限循环体内,直到成功为止。
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
2.2 Unsafe
从类名就可知,Unsafe操作是非安全的操作,比如:
根据偏移量设置值(在刚刚介绍的AtomicInteger中已经看到了这个功能)
park()(把这个线程停下来,在以后的Blog中会提到)
底层的CAS操作
非公开API,在不同版本的JDK中,可能有较大差异
2.3. AtomicReference
前面已经提到了AtomicInteger,当然还有AtomicBoolean,AtomicLong等等,都大同小异。
这里要介绍的是AtomicReference。
AtomicReference是一种模板类
public class AtomicReference&V&
implements java.io.Serializable
它可以用来封装任意类型的数据。
比如String
import java.util.concurrent.atomic.AtomicR
public class Test
public final static AtomicReference&String& atomicString = new AtomicReference&String&(&hosee&);
public static void main(String[] args)
for (int i = 0; i & 10; i++)
final int num =
new Thread() {
public void run() {
Thread.sleep(Math.abs((int)Math.random()*100));
catch (Exception e)
e.printStackTrace();
if (atomicString.compareAndSet(&hosee&, &ztk&))
System.out.println(Thread.currentThread().getId() + &Change value&);
System.out.println(Thread.currentThread().getId() + &Failed&);
}.start();
9Change value
可以看到只有一个线程能够修改值,并且后面的线程都不能再修改。
2.4.AtomicStampedReference
我们会发现CAS操作还是有一个问题的
比如之前的AtomicInteger的incrementAndGet方法
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
假设当前value=1当某线程int current = get()执行后,切换到另一个线程,这个线程将1变成了2,然后又一个线程将2又变成了1。此时再切换到最开始的那个线程,由于value仍等于1,所以还是能执行CAS操作,当然加法是没有问题的,如果有些情况,对数据的状态敏感时,这样的过程就不被允许了。
此时就需要AtomicStampedReference类。
其内部实现一个Pair类来封装值和时间戳。
private static class Pair&T& {
private Pair(T reference, int stamp) {
this.reference =
this.stamp =
static &T& Pair&T& of(T reference, int stamp) {
return new Pair&T&(reference, stamp);
这个类的主要思想是加入时间戳来标识每一次改变。
//比较设置 参数依次为:期望值 写入新值 期望时间戳 新时间戳
public boolean compareAndSet(V
expectedReference,
newReference,
int expectedStamp,
int newStamp) {
Pair&V& current =
expectedReference == current.reference &&
expectedStamp == current.stamp &&
((newReference == current.reference &&
newStamp == current.stamp) ||
casPair(current, Pair.of(newReference, newStamp)));
当期望值等于当前值,并且期望时间戳等于现在的时间戳时,才写入新值,并且更新新的时间戳。
这里举个用AtomicStampedReference的场景,可能不太适合,但是想不到好的场景了。
场景背景是,某公司给余额少的用户免费充值,但是每个用户只能充值一次。
import java.util.concurrent.atomic.AtomicStampedR
public class Test
static AtomicStampedReference&Integer& money = new AtomicStampedReference&Integer&(
public static void main(String[] args)
for (int i = 0; i & 3; i++)
final int timestamp = money.getStamp();
new Thread()
public void run()
while (true)
while (true)
Integer m = money.getReference();
if (m & 20)
if (money.compareAndSet(m, m + 20, timestamp,
timestamp + 1))
System.out.println(&充值成功,余额:&
+ money.getReference());
}.start();
new Thread()
public void run()
for (int i = 0; i & 100; i++)
while (true)
int timestamp = money.getStamp();
Integer m = money.getReference();
if (m & 10)
if (money.compareAndSet(m, m - 10, timestamp,
timestamp + 1))
System.out.println(&消费10元,余额:&
+ money.getReference());
Thread.sleep(100);
catch (Exception e)
// TODO: handle exception
}.start();
解释下代码,有3个线程在给用户充值,当用户余额少于20时,就给用户充值20元。有100个线程在消费,每次消费10元。用户初始有9元,当使用AtomicStampedReference来实现时,只会给用户充值一次,因为每次操作使得时间戳+1。运行结果:
充值成功,余额:39
消费10元,余额:29
消费10元,余额:19
消费10元,余额:9
如果使用AtomicReference&Integer&或者 Atomic Integer来实现就会造成多次充值。
充值成功,余额:39
消费10元,余额:29
消费10元,余额:19
充值成功,余额:39
消费10元,余额:29
消费10元,余额:19
充值成功,余额:39
消费10元,余额:29
2.5. AtomicIntegerArray
与AtomicInteger相比,数组的实现不过是多了一个下标。
public final boolean compareAndSet(int i, int expect, int update) {
return compareAndSetRaw(checkedByteOffset(i), expect, update);
它的内部只是封装了一个普通的array
private final int[]
里面有意思的是运用了二进制数的前导零来算数组中的偏移量。
shift = 31 - Integer.numberOfLeadingZeros(scale);
前导零的意思就是比如8位表示12,,那么前导零就是1前面的0的个数,就是4。
具体偏移量如何计算,这里就不再做介绍了。
2.6. AtomicIntegerFieldUpdater
AtomicIntegerFieldUpdater类的主要作用是让普通变量也享受原子操作。
就比如原本有一个变量是int型,并且很多地方都应用了这个变量,但是在某个场景下,想让int型变成AtomicInteger,但是如果直接改类型,就要改其他地方的应用。AtomicIntegerFieldUpdater就是为了解决这样的问题产生的。
import java.util.concurrent.atomic.AtomicI
import java.util.concurrent.atomic.AtomicIntegerFieldU
public class Test
public static class V{
public int getScore()
public void setScore(int score)
this.score =
public final static AtomicIntegerFieldUpdater&V& vv = AtomicIntegerFieldUpdater.newUpdater(V.class, &score&);
public static AtomicInteger allscore = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException
final V stu = new V();
Thread[] t = new Thread[10000];
for (int i = 0; i & 10000; i++)
t[i] = new Thread() {
public void run()
if(Math.random()&0.4)
vv.incrementAndGet(stu);
allscore.incrementAndGet();
t[i].start();
for (int i = 0; i & 10000; i++)
t[i].join();
System.out.println(&score=&+stu.getScore());
System.out.println(&allscore=&+allscore);
上述代码将score使用 AtomicIntegerFieldUpdater变成 AtomicInteger。保证了线程安全。
这里使用allscore来验证,如果score和allscore数值相同,则说明是线程安全的。
Updater只能修改它可见范围内的变量。因为Updater使用反射得到这个变量。如果变量不可见,就会出错。比如如果某变量申明为private,就是不可行的。
为了确保变量被正确的读取,它必须是volatile类型的。如果我们原有代码中未申明这个类型,那么简单得申明一下就行,这不会引起什么问题。
由于CAS操作会通过对象实例中的偏移量直接进行赋值,因此,它不支持static字段(Unsafe.objectFieldOffset()不支持静态变量)。
写的很好,学习了,确实处理异常是一个需要细心的事
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:ImportNew.
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2018 ImportNew其他回答(4)
园豆:25242
想办法弄成低并发量。
园豆:26036
通俗点说叫分流,前面叫负载均衡,后面叫集群或分布式。
园豆:2442
楼上负载均衡是可以的
清除回答草稿
&&&您需要以后才能回答,未注册用户请先。大神级别Java程序员是如何炼成的
一句话形容:提高开发效率,降低开发成本。但是对程序员来说,这样对个人的成长非常的不利。继续拿出几个问题来反思自己!
有没有动脑子
书写代码的过程中,必然会涉及到N多的老代码的维护,有没有考虑去抽象公用方法,有没有考虑去改造包结构,有没有考虑一些代码上的重构,有没有考虑解决系统的性能瓶颈和可用性的问题?思考是必须的,只有在思考的过程中人才会成长起来。想办法去奉献智慧,人才可能慢慢的成长!
在项目组中,动手去解决问题要比说出自己的想法更加重要。因为在你考虑是否应该这样做的时候,别人很可能就走到了你的前面。所以,在提高软件可用性的前提下,任何的尝试都应该动手去实施,作为行动的巨人。(不要总是想着和系统架构师的想法保持一致了,有些情况下,系统架构师是错误的。)
有没有和高手过招
其实网上很多技术blog写的都很好,尤其那些持续更新的架构和技术的程序员们更是值得学习。找到他们,和他们讨论一个方面的技术。真正的高手都是谦虚的,讨教一些他们知道的东西,这些人会不遗余力的指导你,前提是他们不是很忙。
知识层面是否越来越底层
在平时接触到不同的框架的时候,一般花上一天的时间看看架构图并且理解其中关键环节的配置调用就可以了。但是如果想提高自己的架构水平,还是不断的看别人的源代码,吸取别人思想的精华部分,然后自己在工作中去发挥智慧。Rod Johson写的spring框架也是在不断吸取别人思想的基础上逐渐的发展壮大起来的,在他大声疾呼“develop withoutEJB”的时候,这个人对EJB非常的熟悉,不信的话可以去看看《ExpertOne-on-OneJ2EEDevelopment without EJB》看看前面几章的分析。其实EJB2.0是一个思想库,只是我现在还没有时间去研究这个。
cache对象的时候,有没有考虑到对象的clone,HashMap中的clone的方法是深clone还是浅clone,ArrayList和LinkedList呢?什么时候在创建ExectorService对象的时候使用newFixedThreadPool而不是newCachedThreadPool?javanio你知道多少?如果一开始我写了足够理解并发,积分计算和公共出发拉直的代码我会写成另外一个样子。那个为了改善性能的jobs我TMD也不会写一个quartz的job了。我只能现在慢慢的修改其中代码来提升系统的性能和程序的健壮性。我需要花大功夫研究java的基础知识。
行走江湖,怎么能没有看家本领,其实大部分程序员都没有。有人说自己精通java,但是问到他对concurrent包的了解情况的时候,却是一问三不知。如果是我写简历,我更乐意写:精通java 的并发编程和nio.其他方面当然也需要关注,但是谈到精通就差一点了。
如果和别人聊天的时候,能让别人觉得学到东西,那么你就会感到一种发自内心的成就感和愉悦感。。。
学习技术不怕慢就怕停,每天坚持编码,坚持总结,成为技术大牛还是难事儿。
关注“”微信公众号,获取更多相关资讯,现在报名培训,可免费参加Java初级课程,亲身体验这里的学习氛围,合不合适你来感觉下就知道了。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点

我要回帖

更多关于 血糖高并发症有哪些 的文章

 

随机推荐