最近因为一个项目,改造客户现有系统,因为客户现存计费系统和J2EE化的系统之间界限定义不是很好,为了保证项目在不重构的情况下,很好的优化J2EE化系统,利用Java多线程优势来改造批量计算扣费的优化。没办法,将核心的计算库保留原有c++应用动态库,多线程应用方面采用java这样一个混搭的模式。
这个过程比较的痛苦,其中具体的改造思路涉及业务层面的就不多描述了,主要还是分享下java到c++核心库之间的数据传递的一个简单做法,当然如果有更好的处理技巧,熟悉这方面的专家也可以给我一点意见;
场景:
1、c++核心库,主要负责计算销帐逻辑,输入的数据有账本和账单,账本可以理解为资金,但是是分列式流水记录,账单是用户的消费记录,记录用户消费各类业务的账单;
核心库负责通过销帐的规则,计算账本和账单,最后得出扣减的记录,供结余变化参考。
2、外围独立模块采用java应用,发挥java多线程的优势,采用JNA接口调用c++核心计算库,通过传入数据调用c++核心库完成计算。
过程:
1、一开始我们研究了一下JNI,JNA接口,从性能角度考虑我们选择了JNA的接口,因为批量计算模块处理的数据量非常的大,我们希望在细节上面都去把控他的性能;
2、在数据传递方面因为账本、账单都是一条条记录方式,正常情况都是以String、struct或者容器一类的对象进行传递,但是在经过大量的改造测试,发现就基于struct的数据传递跑通,但是经常会报出不同的内存错误问题,让人很头疼!
3、最后决定数据传递方面还是选择byte字节流方式最好,因此就有了本文一些小的做法。
4、账本和账单对于一个账户来讲会是多条,那么传递数据时候,就需要将这些多条进行拼接,拼接好后按照byte流在java和c++接口之间进行传递;
5、通过分析,拼接字符串方面StringBuffer是个比较高效的做法,相比java里面的String类型,因此java里面的数据采用StringBuffer存放;
6、通常String类型的字符串向byte的字节流转变提供了方便的接口getBytes(),但是StringBuffer到byte数组的转变得考虑怎么转换?
小解决方式:
/**
* Created by wangfeng on 2014-11-18.
*/
public class testByte {
public static void main(String argc[]){
//---------get a StringBuffer
StringBuffer buf=new StringBuffer();
for(int i=0;i<10;i++)
{
buf.append("i="+i+"\n");
}
System.out.println(buf);
System.out.println(buf.length());
//---------StringBuffer convert to byte
byte[] retBuf=new byte[buf.length()];
for(int j=0;j<buf.length();j++)
{
retBuf[j]=Byte.parseByte((int)buf.charAt(j)+"");
}
//print byte
String tmp=new String(retBuf);
System.out.println(tmp);
}
}
运行结果:
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
40
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9