IT神童

java,net,php技术研究神童

2012年8月23日

让Java代码跑得更快

本文简单介绍一下在写代码过程中用到的一些让JAVA代码更高效的技巧。

1,将一些系统资源放在池中,如数据库连接,线程等.在standalone的应用中,数据库连接池可以使用一些开源的连接池实现,如C3P0,proxool和DBCP等,在运行在容器中的应用这可以使用服务器提供的DataSource.线程池可以使用JDK本身就提供的java.util.concurrent.ExecutorService.

  1. import java.util.concurrent.Executors;  
  2. import java.util.concurrent.ExecutorService;  
  3. public class JavaThreadPool {  
  4.     public static void main(String[] args) {  
  5.     ExecutorService pool = Executors.newFixedThreadPool(2);  
  6.       
  7.     Thread t1 = new MyThread();  
  8.     Thread t2 = new MyThread();  
  9.     Thread t3 = new MyThread();  
  10.     Thread t4 = new MyThread();  
  11.     Thread t5 = new MyThread();  
  12.  
  13.     pool.execute(t1);  
  14.     pool.execute(t2);  
  15.     pool.execute(t3);  
  16.     pool.execute(t4);  
  17.  
  18.     pool.shutdown();  
  19.     }  
  20. }  
  21.  
  22. class MyThread extends Thread {  
  23.     public void run() {  
  24.     System.out.println(Thread.currentThread().getName() + "running....");  
  25.     }  
  26. }  

2,减少网络开销,在和数据库或者远程服务交互的时候,尽量将多次调用合并到一次调用中。

3,将经常访问的外部资源cache到内存中,简单的可以使用static的hashmap在应用启动的时候加载,也可以使用一些开源的cache框架,如OSCache和Ehcache等.和资源的同步可以考虑定期轮询和外部资源更新时候主动通知.或者在自己写的代码中留出接口(命令方式或者界面方式)共手动同步。

4,优化IO操作,JAVA操作文件的时候分InputStream and OutputStream,Reader and Writer两类,stream的方式要快,后者主要是为了操作字符而用的,在字符仅仅是ASCII的时候可以用stream的方式提高效率.JDK1.4之后的nio比io的效率更好。java教程下载

  1. OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("d:/temp/test.txt")));              
  2. out.write("abcde".getBytes());        
  3. out.flush();  
  4. out.close(); 

利用BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter减少对磁盘的直接访问次数。

  1. FileReader fr = new FileReader(f);  
  2. BufferedReader br = new BufferedReader(fr);  
  3. while (br.readLine() != null) count++; 

5不要频繁的new对象,对于在整个应用中只需要存在一个实例的类使用单例模式.对于String的连接操作,使用StringBuffer或者StringBuilder.对于utility类型的类通过静态方法来访问。

6,避免使用错误的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace消耗性能,除非必要不要使用instanceof做条件判断,尽量使用比的条件判断方式.使用JAVA中效率高的类,比如ArrayList比Vector性能好。

7,对性能的考虑要在系统分析和设计之初就要考虑。

总之,一个系统运行时的性能,无非是从CPU,Memory和IO这三个主要方面来考虑优化.减少不必要的CPU消耗,减少不必要的IO操作,增加Memory利用效率。

posted @ 2012-08-23 14:42 IT神童 阅读(533) | 评论 (0)编辑 收藏

Java高并发:静态页面生成方案

提升网站性能的方式有很多,例如有效的使用缓存,生成静态页面等等。今天要说的就是生成静态页面的方式。这个也是我近期一直在搞的一个问题,近期在做使用html + servlet做个人网站,为什么是这2个东西呢?

1、直接用servlet是为了保证网站能以最快的速度执行命令个人总感觉像Struts hibernate spring之类的虽然方便但是效能带来的损耗不太能接收

2、使用html同样是为了保证最快的反应速度,毕竟html 比jsp少了一层服务器执行。速度上要快的多

一、在这里要先说一下什么是页面静态化:

简单的说,我们如果访问一个链接 ,服务器对应的模块会处理这个请求,转到对应的jsp界面,最后生成我们想要看到的数据。这其中的缺点是显而易见的:因为每次请求服务器都会进行处理,如果有太多的高并发请求,那么就会加重应用服务器的压力,弄不好就把服务器 搞down 掉了。那么如何去避免呢?如果我们把对 test.do 请求后的结果保存成一个 html 文件,然后每次用户都去访问 ,这样应用服务器的压力不就减少了?

那么静态页面从哪里来呢?总不能让我们每个页面都手动处理吧?这里就牵涉到我们要讲解的内容了,静态页面生成方案… 我们需要的是自动的生成静态页面,当用户访问 ,会自动生成 test.html ,然后显示给用户。

二、下面我们在简单介绍一下要想掌握页面静态化方案应该掌握的知识点

1、 基础- URL Rewrite

什么是 URL Rewrite 呢 ? URL 重写。用一个简单的例子来说明问题:输入网址 ,但是实际上访问的却是 abc.com/test.action,那我们就可以说 URL 被重写了。这项技术应用广泛,有许多开源的工具可以实现这个功能。java电子书免费下载2、 基础- Servlet web.xml

如果你还不知道 web.xml 中一个请求和一个 servlet 是如何匹配到一起的,那么请搜索一下 servlet 的文档。这可不是乱说呀,有很多人就认为 /xyz/*.do 这样的匹配方式能有效。

如果你还不知道怎么编写一个 servlet ,那么请搜索一下如何编写 servlet.这可不是说笑呀,在各种集成工具漫天飞舞的今天,很多人都不会去从零编写一个 servlet了。

三、基本的方案介绍

其中,对于 URL Rewriter的部分,可以使用收费或者开源的工具来实现,如果 url不是特别的复杂,可以考虑在 servlet 中实现,那么就是下面这个样子:
 

posted @ 2012-08-23 14:41 IT神童 阅读(140) | 评论 (0)编辑 收藏

公司的Java框架应具备的通用功能

以前在学校的时候自己以为是不是每个做JAVA开发的公司每次做项目的时候都要搭建一个SSH框架呢,工作之后才发现每个公司都有自己的一套框架,要不是在SSH基础上,要不是在SSI基础上进行了符合自己公司需求的封装,并且随着自己公司的框架被应用到各个实际系统的过程中,这个框架会越来越成熟,会使该公司的开发效率越来越高。

根据笔者接触过的几个公司的框架,笔者发现要想实现高效的开发,每个公司的框架应该具备如下的特点:

1.具有灵活的分页功能。

分页功能是每个项目中必须要实现的功能,而恰恰这个功能是比较费时费力的,如果在框架中实现这一功能,将在每个项目中大大减少分页的重复性工作。

2.可以方便的实现文件的上传与下载、数据的导入和导出的功能。

文件的上传于下载、数据的导入和导出在大部门项目中也会遇到,但是这两个功能可能会因为项目的不同导致实现上有一点区别,我们框架中要做的就是应该抽出其中共有的东西,定义为抽象的东西,以便不同的项目、不同的需求都能很容易的实现该功能。成都java培训机构
3.方便的事务管理功能。

事务管理一般来说都定义在业务逻辑层。我们框架中应该实现对业务逻辑对象事务的简单配置甚至是零配置。笔者接触过的两个框架中,一个需要在配置完一个业务逻辑对象时,在事务管理的配置文件中加上一句简单的配置即可,另一个是框架中实现了几个基本的业务逻辑对象,并对这几个对象实现了事务管理的配置,开发的时候定义的业务逻辑对象都是继承自这几个基本对象,也就省去了事务管理的配置。

4.具有异常处理框架。

基本上每个项目的异常处理都应该可以使用公司的框架定义的异常处理框架,并不会因为项目的不同而要求的异常处理也不一样。

5.具有自己的一套页面组件。

项目开发都是团队的开发,要想保证每个开发人员的界面风格统一,最好的办法就是定义一套公司自己的页面组建。这样既能保证开发效率,也能做到界面的统一。freemark就是不错的选择,其支持自定义宏,公司框架中可以定义一套自己的页面组建宏,供开发人员调用即可。


 

6.具有数据校验框架。

每个项目在数据校验时都可能会用到大量的正则表达式,那么在公司的框架中将这些正则表达式封装起来,提供统一的调用接口将是不错的选择。

7.简单的实现菜单的配置。

一个好的框架应该提供对菜单、二级菜单等的简单配置、管理。还是上文提到的两个框架,一个是通过XML配置文件实现了对系统中一级菜单、二级菜单、三级菜单的管理,而另个框架要实现相同的需求却要在数据库中进行繁琐的配置,显然第一个框架的实现方案更可取、更高效。

posted @ 2012-08-23 14:40 IT神童 阅读(262) | 评论 (1)编辑 收藏

Java中用内存映射处理大文件

在处理大文件时,如果利用普通的FileInputStream 或者FileOutputStream 抑或RandomAccessFile 来进行频繁的读写操作,都将导致进程因频繁读写外存而降低速度.如下为一个对比实验。

  1. package test;  
  2.  
  3. import java.io.BufferedInputStream;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.IOException;  
  7. import java.io.RandomAccessFile;  
  8. import java.nio.MappedByteBuffer;  
  9. import java.nio.channels.FileChannel;  
  10.  
  11. public class Test {  
  12.  
  13.       
  14.     public static void main(String[] args) {  
  15.         try {  
  16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  17.             int sum=0;  
  18.             int n;  
  19.             long t1=System.currentTimeMillis();  
  20.             try {  
  21.                 while((n=fis.read())>=0){  
  22.                     sum+=n;  
  23.                 }  
  24.             } catch (IOException e) {  
  25.                 // TODO Auto-generated catch block  
  26.                 e.printStackTrace();  
  27.             }  
  28.             long t=System.currentTimeMillis()-t1;  
  29.             System.out.println("sum:"+sum+"  time:"+t);  
  30.         } catch (FileNotFoundException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         }  
  34.           
  35.         try {  
  36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  37.             BufferedInputStream bis=new BufferedInputStream(fis);  
  38.             int sum=0;  
  39.             int n;  
  40.             long t1=System.currentTimeMillis();  
  41.             try {  
  42.                 while((n=bis.read())>=0){  
  43.                     sum+=n;  
  44.                 }  
  45.             } catch (IOException e) {  
  46.                 // TODO Auto-generated catch block  
  47.                 e.printStackTrace();  
  48.             }  
  49.             long t=System.currentTimeMillis()-t1;  
  50.             System.out.println("sum:"+sum+"  time:"+t);  
  51.         } catch (FileNotFoundException e) {  
  52.             // TODO Auto-generated catch block  
  53.             e.printStackTrace();  
  54.         }  
  55.           
  56.         MappedByteBuffer buffer=null;  
  57.         try {  
  58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 01253244);  
  59.             int sum=0;  
  60.             int n;  
  61.             long t1=System.currentTimeMillis();  
  62.             for(int i=0;i<1253244;i++){  
  63.                 n=0x000000ff&buffer.get(i);  
  64.                 sum+=n;  
  65.             }  
  66.             long t=System.currentTimeMillis()-t1;  
  67.             System.out.println("sum:"+sum+"  time:"+t);  
  68.         } catch (FileNotFoundException e) {  
  69.             // TODO Auto-generated catch block  
  70.             e.printStackTrace();  
  71.         } catch (IOException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         }  
  75.  
  76.     }  
  77.  
  78. }  
java基础教程
测试文件为一个大小为1253244字节的文件。测试结果:
  1. sum:220152087 time:1464  
  2. sum:220152087 time:72  
  3. sum:220152087 time:25 

说明读数据无误。删去其中的数据处理部分。

  1. package test;  
  2.  
  3. import java.io.BufferedInputStream;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.IOException;  
  7. import java.io.RandomAccessFile;  
  8. import java.nio.MappedByteBuffer;  
  9. import java.nio.channels.FileChannel;  
  10.  
  11. public class Test {  
  12.  
  13.       
  14.     public static void main(String[] args) {  
  15.         try {  
  16.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  17.             int sum=0;  
  18.             int n;  
  19.             long t1=System.currentTimeMillis();  
  20.             try {  
  21.                 while((n=fis.read())>=0){  
  22.                     //sum+=n;  
  23.                 }  
  24.             } catch (IOException e) {  
  25.                 // TODO Auto-generated catch block  
  26.                 e.printStackTrace();  
  27.             }  
  28.             long t=System.currentTimeMillis()-t1;  
  29.             System.out.println("sum:"+sum+"  time:"+t);  
  30.         } catch (FileNotFoundException e) {  
  31.             // TODO Auto-generated catch block  
  32.             e.printStackTrace();  
  33.         }  
  34.           
  35.         try {  
  36.             FileInputStream fis=new FileInputStream("/home/tobacco/test/res.txt");  
  37.             BufferedInputStream bis=new BufferedInputStream(fis);  
  38.             int sum=0;  
  39.             int n;  
  40.             long t1=System.currentTimeMillis();  
  41.             try {  
  42.                 while((n=bis.read())>=0){  
  43.                     //sum+=n;  
  44.                 }  
  45.             } catch (IOException e) {  
  46.                 // TODO Auto-generated catch block  
  47.                 e.printStackTrace();  
  48.             }  
  49.             long t=System.currentTimeMillis()-t1;  
  50.             System.out.println("sum:"+sum+"  time:"+t);  
  51.         } catch (FileNotFoundException e) {  
  52.             // TODO Auto-generated catch block  
  53.             e.printStackTrace();  
  54.         }  
  55.           
  56.         MappedByteBuffer buffer=null;  
  57.         try {  
  58.             buffer=new RandomAccessFile("/home/tobacco/test/res.txt","rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 01253244);  
  59.             int sum=0;  
  60.             int n;  
  61.             long t1=System.currentTimeMillis();  
  62.             for(int i=0;i<1253244;i++){  
  63.                 //n=0x000000ff&buffer.get(i);  
  64.                 //sum+=n;  
  65.             }  
  66.             long t=System.currentTimeMillis()-t1;  
  67.             System.out.println("sum:"+sum+"  time:"+t);  
  68.         } catch (FileNotFoundException e) {  
  69.             // TODO Auto-generated catch block  
  70.             e.printStackTrace();  
  71.         } catch (IOException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         }  
  75.  
  76.     }  
  77.  

测试结果:

  1. sum:0 time:1458  
  2. sum:0 time:67  
  3. sum:0 time:8 

由此可见,将文件部分或者全部映射到内存后进行读写,速度将提高很多。

这是因为内存映射文件首先将外存上的文件映射到内存中的一块连续区域,被当成一个字节数组进行处理,读写操作直接对内存进行操作,而后再将内存区域重新映射到外存文件,这就节省了中间频繁的对外存进行读写的时间,大大降低了读写时间。

posted @ 2012-08-23 14:37 IT神童 阅读(207) | 评论 (0)编辑 收藏

<2012年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜