《Java程序性能优化》说性能优化包含五个层次:设计调优、代码调优、JVM调优、数据库调优、操作系统调优。

常用的几个代码优化方案:

使用单例

对于IO处理、数据库连接、配置文件解析加载等一些非常耗费系统资源的操作,我们必须对这些实例的创建进行限制,或者是始终使用一个公用的实例,以节约系统开销,这种情况下就需要用到单例模式。

使用Future模式

假设一个任务执行起来需要花费一些时间,为了省去不必要的等待时间,可以先获取一个“提货单”,即Future,然后继续处理别的任务,直到“货物”到达,即任务执行完得到结果,此时便可以用“提货单”进行提货,即通过Future对象得到返回值。

  1. public class RealData implements Callable<String> {
  2. protected String data;
  3. public RealData(String data) {
  4. this.data = data;
  5. }
  6. @Override
  7. public String call() throws Exception {
  8. //利用sleep方法来表示真是业务是非常缓慢的
  9. try {
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. return data;
  15. }
  16. }
  17. public class Application {
  18. public static void main(String[] args) throws Exception {
  19. FutureTask<String> futureTask =
  20. new FutureTask<String>(new RealData("name"));
  21. ExecutorService executor =
  22. Executors.newFixedThreadPool(1); //使用线程池
  23. //执行FutureTask,相当于上例中的client.request("name")发送请求
  24. executor.submit(futureTask);
  25. //这里可以用一个sleep代替对其他业务逻辑的处理
  26. //在处理这些业务逻辑过程中,RealData也正在创建,从而充分了利用等待时间
  27. Thread.sleep(2000);
  28. //使用真实数据
  29. //如果call()没有执行完成依然会等待
  30. System.out.println("数据=" + futureTask.get());
  31. }
  32. }

使用线程池

合理利用线程池能够带来三个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

在 Java 5 之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor 框架便是 Java 5 中引入的,其内部使用了线程池机制,它在 java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。

  1. public class MultiThreadTest {
  2. public static void main(String[] args) {
  3. ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-%d").build();
  4. ExecutorService executor = new ThreadPoolExecutor(2, 5, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
  5. executor.execute(new Runnable() {
  6. @Override
  7. public void run() {
  8. System.out.println("hello world !");
  9. }
  10. });
  11. System.out.println(" ===> main Thread! " );
  12. }
  13. }

使用NIO

JDK自1.4起开始提供全新的I/O编程类库,简称NIO,其不但引入了全新高效的Buffer和Channel,同时,还引入了基于Selector的非阻塞 I/O机制,将多个异步的I/O操作集中到一个或几个线程当中进行处理,使用NIO代替阻塞I/O能提高程序的并发吞吐能力,降低系统的开销。

对于每一个请求,如果单独开一个线程进行相应的逻辑处理,当客户端的数据传递并不是一直进行,而是断断续续的,则相应的线程需要 I/O等待,并进行上下文切换。而使用NIO引入的Selector机制后,可以提升程序的并发效率,改善这一状况。

  1. public class NioTest {
  2. static public void main( String args[] ) throws Exception {
  3. FileInputStream fin = new FileInputStream("c:\\test.txt");
  4. // 获取通道
  5. FileChannel fc = fin.getChannel();
  6. // 创建缓冲区
  7. ByteBuffer buffer = ByteBuffer.allocate(1024);
  8. // 读取数据到缓冲区
  9. fc.read(buffer);
  10. buffer.flip();
  11. while (buffer.remaining()>0) {
  12. byte b = buffer.get();
  13. System.out.print(((char)b));
  14. }
  15. fin.close();
  16. }
  17. }

锁优化

在并发场景中,我们的代码中经常会用到锁。存在锁,就必然存在锁的竞争,存在锁的竞争,就会消耗很多资源。那么,如何优化我们Java代码中的锁呢?主要可以从以下几个方面考虑:

  • 减少锁持有时间(可以使用同步代码块来代替同步方法。这样既可以减少锁持有的时间。)
  • 减少锁粒度(要在并发场景中使用Map的时候,记得使用ConcurrentHashMap来代替HashTable和HashMap。)
  • 锁分离(普通锁(如syncronized)会导致读阻塞写、写也会阻塞读,同时读读与写写之间也会进行阻塞,可以想办法将读操作和写操作分离开。)
  • 锁粗化(有些情况下我们希望把很多次锁的请求合并成一个请求,以降低短时间内大量锁请求、同步、释放带来的性能损耗。)
  • 锁消除(锁消除是Java虚拟机在JIT编译是,通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过锁消除,可以节省毫无意义的请求锁时间。)

压缩传输

在进行数据传输之前,可以先将数据进行压缩,以减少网络传输的字节数,提升数据传输的速度,接收端可以将数据进行解压,以还原出传递的数据,并且,经过压缩的数据还可以节约所耗费的存储介质(磁盘或内存)的空间以及网络带宽,降低成本。当然,压缩也并不是没有开销的,数据压缩需要大量的CPU计算,并且,根据压缩算法的不同,计算的复杂度以及数据的压缩比也存在较大差异。一般情况下,需要根据不同的业务场景,选择不同的压缩算法。

缓存结果

对于相同的用户请求,如果每次都重复的查询数据库,重复的进行计算,将浪费很多的时间和资源。将计算后的结果缓存到本地内存,或者是通过分布式缓存来进行结果的缓存,可以节约宝贵的CPU计算资源,减少重复的数据库查询或者是磁盘I/O,将原本磁头的物理转动变成内存的电子运动,提高响应速度,并且线程的迅速释放也使得应用的吞吐能力得到提升

转载:

原文地址:人人都能掌握的Java服务端性能优化方案

Java服务端性能优化的更多相关文章

  1. 人人都能掌握的Java服务端性能优化方案

    作为一个Java后端开发,我们写出的大部分代码都决定着用户的使用体验.如果我们的后端代码性能不好,那么用户在访问我们的网站时就要浪费一些时间等待服务器的响应.这就可能导致用户投诉甚至用户的流失. 关于 ...

  2. Web服务端性能提升实践

    随着互联网的不断发展,日常生活中越来越多的需求通过网络来实现,从衣食住行到金融教育,从口袋到身份,人们无时无刻不依赖着网络,而且越来越多的人通过网络来完成自己的需求. 作为直接面对来自客户请求的Web ...

  3. Java 服务端入门和进阶指南

    作者:谢龙 链接:https://www.zhihu.com/question/29581524/answer/44872235 来源:知乎 著作权归作者所有,转载请联系作者获得授权. 现在互联网上资 ...

  4. 那些年,我们见过的 Java 服务端“问题”

    导读 明代著名的心学集大成者王阳明先生在<传习录>中有云: 道无精粗,人之所见有精粗.如这一间房,人初进来,只见一个大规模如此.处久,便柱壁之类,一一看得明白.再久,如柱上有些文藻,细细都 ...

  5. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  6. 5种kafka消费端性能优化方法

    摘要:带你了解基于FusionInsight HD&MRS的5种kafka消费端性能优化方法. 本文分享自华为云社区<FusionInsight HD&MRSkafka消费端性能 ...

  7. Java 服务端监控方案(四. Java 篇)

    http://jerrypeng.me/2014/08/08/server-side-java-monitoring-java/ 这个漫长的系列文章今天要迎来最后一篇了,也是真正与 Java 有关的部 ...

  8. 那些年,我们见过的 Java 服务端乱象

    导读 查尔斯·狄更斯在<双城记>中写道:“这是一个最好的时代,也是一个最坏的时代.” 移动互联网的快速发展,出现了许多新机遇,很多创业者伺机而动:随着行业竞争加剧,互联网红利逐渐消失,很多 ...

  9. 那些年,我们见过的Java服务端乱象

    导读 查尔斯·狄更斯在<双城记>中写道:“这是一个最好的时代,也是一个最坏的时代.”移动互联网的快速发展,出现了许多新机遇,很多创业者伺机而动:随着行业竞争加剧,互联网红利逐渐消失,很多创 ...

随机推荐

  1. vue中使用AES.js和crypto.js加密

    一:crypto-js加密 1.1:安装依赖 npm install crypto-js --save-dev 1.2 :在项目目录上创建一个js文件里面写入加密,解密的代码 mport Crypto ...

  2. Typecho 主题更换

    Typecho 主题更换 前言 上一篇已经搭建自己的 Typecho 博客,博客搭建完成自带一个默认主题,不是很喜欢默认的主题,想换一个自己喜欢的主题,并在基础上进行修改. 本文就介绍下如何更换和自定 ...

  3. Lagom 官方文档之随手记

    引言 Lagom是出品Akka的Lightbend公司推出的一个微服务框架,目前最新版本为1.6.2.Lagom一词出自瑞典语,意为"适量". https://www.lagomf ...

  4. 3.k8s存储之ConfigMap、Secret

    1.ConfigMap ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件.命令行参数或环境变量中读取配置信息.ConfigMap API 给我们提供了向容器 ...

  5. Dubbo 就是靠它崭露头角!(身为开源框架很重要的一点)

    Hola,我是 yes. 经过了 RPC 核心和 Dubbo 微内核两篇文章后,今天终于要稍稍深入一波 Dubbo 了. 作为一个通用的 RPC 框架,性能是很重要的一环,而易用性和扩展性也极为重要. ...

  6. ruby+watir安装指南

    安装ruby+watir一共需要下面几个步骤 1. 安装ruby: 2. 升级Rubygems:Rubygems(简称 gems)是一个用于对 Ruby组件进行打包的 Ruby 打包系统. 它提供一个 ...

  7. ClickHouse安装使用(单机、集群、高可用)

    Clickhouse版本:20.3.6.40-2 安装包地址:https://repo.yandex.ru/clickhouse/rpm/stable/x86_64/ 一.单机版 1.安装依赖 yum ...

  8. Spring Cloud微服务Sentinel+Apollo限流、熔断实战总结

    在Spring Cloud微服务体系中,由于限流熔断组件Hystrix开源版本不在维护,因此国内不少有类似需求的公司已经将眼光转向阿里开源的Sentinel框架.而以下要介绍的正是作者最近两个月的真实 ...

  9. 【Nginx】使用keepalive和nginx搭载高可用

    首先介绍一下Keepalived,它是一个高性能的服务器高可用或热备解决方案,Keepalived主要来防止服务器单点故障的发生问题,可以通过其与Nginx的配合实现web服务端的高可用. Keepa ...

  10. SwiftUI 官方画图实例详细解析

    前言 在前面几篇关于SwiftUI的文章中,我们用一个具体的基本项目Demo来学习了下SwiftUI,里面包含了常见的一些控件使用以及数据处理和地图等等,有兴趣的小伙伴可以去翻翻以前的文章,在前面总结 ...