首先,介绍…

我有一组类,它们从同一类Feature继承,但是彼此不同,因为它们每个都使用不同的信息进行计算.所以这是一个例子:

public class FeatureA extends Feature

{

private MyTableA table = null;

public FeatureA(final String fName, final MyTableA table) {

super(fName);

this.table = table;

}

public Double compute(String input)

{

return table.computeProduct(String input);

}

}

public class MyTableA {

private static HashMap map1 = null;

private static HashMap map2 = null;

public MyTableA(final String serFilePath)

{

// map1 and map2 are deserizlied here from serFilePath

}

public Double computeProduct(String input)

{

Integer val1 = map1.get(input);

Double val2 = map2.get(input);

Double res = val1 * val2;

return res;

}

因此FeatureA依赖于对象MyTableA,并且在加载我的应用程序时会反序列化该对象.

该应用是多线程的,具有独立的线程以相同的方式处理不同的输入数据令牌.对于每个令牌,我都会计算特征值,包括FeatureA. MyTableA对于所有数据令牌都是相同的(作为一个简单的示例,功能可能是某人的电话号码,该电话号码是通过他们的名字在单个全局电话簿中查找的.

现在,问题…

我一直在为系统添加越来越多的功能,每个新功能都增加了一点额外的处理时间.我又添加了一个,突然我的程序运行慢了很多.比没有它的版本慢10倍.我一直在设法查明问题的根源,但没有多大运气.

问题:是否有可能是由于多个线程尝试从同一静态对象进行map1.get(input)和map2.get(input)引起的?如果是这样,我该如何解决?

更新:该应用程序具有服务器和客户端组件,多线程服务器从客户端的多个副本获取数据令牌.实际上,有3台RedHat机器正在使用:每台机器上运行1台服务器副本和大约100台客户端副本.来自所有3台计算机的客户端将数据发送到所有3台服务器(因此,machine1上的客户端不仅将数据发送到server1).我已经使用过这样的探查器:java -agentlib:hprof = cpu = samples …在这种情况下,这是探查的正确方法吗?

以下是“快速”情况(即功能较少)和“慢速”情况(功能较多)的前5条迹线. java.io.FileInputStream.read0在开始时是一堆地图反序列化的一部分.

Server1_Fast:rank self accum count trace method

Server1_Fast- 1 73.21% 73.21% 405018 300953 java.net.PlainSocketImpl.socketAccept

Server1_Fast- 2 5.63% 78.84% 31145 300698 java.io.FileInputStream.read0

Server1_Fast- 3 4.33% 83.16% 23928 301032 java.lang.UNIXProcess.waitForProcessExit

Server1_Fast- 4 4.28% 87.45% 23685 301031 java.io.FileInputStream.readBytes

Server1_Fast- 5 4.08% 91.53% 22570 301001 java.net.SocketInputStream.socketRead0

--

Server1_Slow:rank self accum count trace method

Server1_Slow- 1 43.66% 43.66% 374607 301136 java.lang.UNIXProcess.forkAndExec

Server1_Slow- 2 23.38% 67.04% 200653 301130 java.io.FileInputStream.readBytes

Server1_Slow- 3 9.74% 76.78% 83571 301058 java.net.PlainSocketImpl.socketAccept

Server1_Slow- 4 7.44% 84.23% 63876 301131 java.lang.UNIXProcess.waitForProcessExit

Server1_Slow- 5 3.70% 87.92% 31711 300690 java.io.FileInputStream.read0

--

Server2_Fast:rank self accum count trace method

Server2_Fast- 1 76.35% 76.35% 427397 300917 java.net.PlainSocketImpl.socketAccept

Server2_Fast- 2 5.21% 81.57% 29183 300690 java.io.FileInputStream.read0

Server2_Fast- 3 4.23% 85.80% 23689 300965 java.net.SocketInputStream.socketRead0

Server2_Fast- 4 4.12% 89.92% 23083 300691 java.io.FileInputStream.readBytes

Server2_Fast- 5 3.09% 93.02% 17320 300993 java.lang.UNIXProcess.waitForProcessExit

--

Server2_Slow:rank self accum count trace method

Server2_Slow- 1 50.19% 50.19% 173210 301024 java.net.PlainSocketImpl.socketAccept

Server2_Slow- 2 9.10% 59.28% 31391 300686 java.io.FileInputStream.read0

Server2_Slow- 3 6.81% 66.09% 23507 300687 java.io.FileInputStream.readBytes

Server2_Slow- 4 5.44% 71.54% 18789 301094 java.lang.UNIXProcess.waitForProcessExit

Server2_Slow- 5 5.38% 76.92% 18571 301093 java.io.FileInputStream.readBytes

--

Server3_Fast:rank self accum count trace method

Server3_Fast- 1 73.38% 73.38% 410860 300954 java.net.PlainSocketImpl.socketAccept

Server3_Fast- 2 6.81% 80.20% 38134 300692 java.io.FileInputStream.read0

Server3_Fast- 3 4.95% 85.14% 27700 300693 java.io.FileInputStream.readBytes

Server3_Fast- 4 3.76% 88.91% 21071 301038 java.lang.UNIXProcess.waitForProcessExit

Server3_Fast- 5 3.75% 92.65% 20974 301037 java.io.FileInputStream.readBytes

--

Server3_Slow:rank self accum count trace method

Server3_Slow- 1 48.32% 48.32% 166867 301048 java.net.PlainSocketImpl.socketAccept

Server3_Slow- 2 10.62% 58.94% 36686 300693 java.io.FileInputStream.read0

Server3_Slow- 3 8.19% 67.13% 28280 300690 java.io.FileInputStream.readBytes

Server3_Slow- 4 5.22% 72.35% 18022 301119 java.lang.UNIXProcess.waitForProcessExit

Server3_Slow- 5 5.06% 77.41% 17464 301118 java.io.FileInputStream.readBytes

此信息是否可以说明问题?

解决方法:

通常,如果您有很多线程在使用(即读取和更新)共享Map对象,则:

>如果未正确同步,则代码将不是线程安全的.这可能会给您带来各种错误的行为,这些行为可能难以复制,并且可能与平台有关.

>如果您确实正确同步,则共享Map将成为潜在的性能瓶颈.但是,这是否是一个实际的瓶颈取决于Map的实现和/或实现同步的方式以及工作量.

Is it possible that the slowdown is caused by multiple threads trying to map1.get(input) and map2.get(input) from the same static objects?

对的,这是可能的. (它是静态的并不重要.关键点是对象由多个线程共享.)

真正的问题也有可能完全不同.例如关于您添加的功能的一些信息,或者您尚未向我们透露的其他信息.

If so, how could I fix this?

鉴于您所提供的详细程度,无法说. (您提供的代码显然是一个“模型”.我们无法从中学习到任何东西.)

如果以上假设正确,则选择其他Map类或其他同步/锁定方案可能会有所帮助.

但是,这只是猜测.尝试解决性能问题时,您不应依赖猜测.最好使用探查器来识别实际的性能瓶颈,然后找出导致它们的原因.例如是争执,还是其他完全是真正的问题.

标签:performance,multithreading,java

来源: https://codeday.me/bug/20191118/2029921.html

静态对象线程java_慢速多线程Java应用程序:这是由于访问静态对象引起的吗?...相关推荐

  1. 苹果系统手机调用java线程出错_在多线程Java应用程序中调用已编译的m-file(.jar)时出错...

    我有一个简单的M文件 function [fRate,Height,Width] = media(filename) obj = mmreader(filename); fRate = obj.Fra ...

  2. 编写多线程Java应用程序常见问题

    几乎所有使用 AWT 或 Swing 编写的画图程序都需要多线程.但多线程程序会造成许多困难,刚开始编程的开发者常常会发现他们被一些问题所折磨,例如不正确的程序行为或死锁. 在本文中,我们将探讨使用多 ...

  3. 编写多线程Java应用程序

    当编写使用AWT或Swing的图形程序时,除了最琐碎的程序之外,其他所有程序都需要多线程. 线程编程带来了许多困难,许多开发人员经常发现自己容易陷入诸如错误的应用程序行为和死锁的应用程序之类的问题. ...

  4. tomcat中设置Java 客户端程序的http(https)访问代理

    1.假定http/https代理服务器为 127.0.0.1 端口为8118 2.在tomcat/bin/catalina.sh脚本文件中设置JAVA_OPTS,如下图: 保存后重启tomcat就能生 ...

  5. java点击按钮结线程_多线程的Java应用程序在调试工具Netbeans中单击“停止”按钮时输出一个奇怪的结果...

    我使用wait()和notify()机制学习了java中的多线程. 但我很好奇输出一个简单的多线程Java应用程序. 代码如下: class Q { int n; boolean valueSet = ...

  6. java csp_Java程序员CSP,第2部分

    CSP是用于对并发对象之间的复杂交互进行建模的范例. 使用CSP的主要优点之一是能够精确地指定和验证程序每个阶段涉及的对象的行为. CSP的理论和实践对并发设计和编程领域产生了深远的影响. 它是occ ...

  7. java csp_Java程序员CSP,第1部分

    众所周知,Java平台上的多线程编程是一项艰巨的任务. 实际上,一般的理论似乎是,多线程编程最好留给Java专家处理. Sun Microsystems通过将以下内容声明为EJB体系结构的目标之一(在 ...

  8. java的应用程序开发_开发一个Java应用程序(1)

    开发一个Java应用程序(1) App Engine上的Java Web应用程序通过Java Servlet标准接口与应用程序服务器交互.一个应用程序由一个或多个类组成,这些类都扩展自一个servle ...

  9. Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空

    Spring Boot 异步线程静态获取request对象为空 RequestContextHolder 为空 Java 异步线程获取request为空 一.问题描述 在Spring Boot的web ...

最新文章

  1. 每个php允许的内存大小,php – 允许的内存大小为262144字节用尽(试图分配24576字节)...
  2. Nature Methods:Rob Knight发布Striped UniFrac算法轻松分析微生物组大数据
  3. python使用ORM之如何调用多对多关系
  4. android Matrix图片变换处理
  5. 如何用最短的时间学会C语言,并掌握C语言的精髓所在?
  6. 启动失败代码2_菲斯曼燃气壁挂炉故障代码大全及解决方法
  7. python组成结构_Python数据分析丨pandas基本数据结构组成
  8. linux系统声卡安装教程,Linux系统下如何安装声卡驱动?
  9. vim默认设置的配置
  10. DML和DQL 总结
  11. 实现 iOS UICollectionView的事件透传
  12. LightGBM算法解析
  13. 举例说明儿化音的作用_六年级语文下学期复习资料
  14. 请求 Provisional headers are shown 问题
  15. JS怎么获取当月最后一天
  16. java中boot是什么,Spring boot是什么
  17. 巧妙使用多个旧路由器无线中继提升网络速度
  18. java编写一个圆环类Ring_编写一个圆环类ring的java程序
  19. Acwing第 62 场周赛【未完结】
  20. Flex 非常实用的资料

热门文章

  1. win7升级win10后出现VisualSVN Server提供程序无法执行所尝试的操作 0x80041024
  2. ​从小样本学习出发,奔向星辰大海
  3. 智能感知与学习(六):识别系统
  4. MyISAM InnoDB 怎么读
  5. I met my soulmate. She didn't.
  6. 有关PHP文档生成工具---PHPDocumentor
  7. 数字化转型的趋势、挑战与战略
  8. 如何产生一个全局唯一的流水号(附demo)
  9. visualDL(一)scalar标量图
  10. 深度学习——损失函数(Regression Loss、Classification Loss)