JMS连接有可能出现异常,对于同步处理(MessageProducer发送或者MessageConsumer调用receive方法)来说,因为是主动调用的,因此可以通过简单的定时重发来重新创建连接。如果是异步接收,即通过实现MessageListener,就比较麻烦,因为是别人回调你的代码。
这里当然需要使用ExceptionListener,来监听jms连接异常。并在异常发生后做一些事情,比如试图恢复连接,如果不能恢复,间隔一段时间再试图连接。
以前做法,是ExceptionListener监听到异常后,在onException方法中设置一个标志对象,另外有一个线程来定时监听这个标志对象,发现异常后做连接的恢复,并重建和注册MessageListener和ExceptionListener到连接。方法比较混乱和复杂。
定时任务有两种:
- 固定延时的定时任务,即一个任务结束等待固定时间后再执行下一个;
- 固定频率的定时任务,即任务在固定时常后开始执行。
举个例子,好比列车调度,比如上海到北京的列车,从上海到达北京后,休息10小时再返回,这就相当于固定延时的定时任务;如果从上海出发是下午3点,到达北京后,比如是上午5点,下午3点再返回上海,这就是固定频率的任务。
这里要注意,固定频率定时任务并不会并发,还是用列车调度举例,如果列车晚点,下午4点到北京,固定频率定时任务并不是在下午3点再调度一列新车发往上海,而是延误的列车到京后立即出发返回。而固定延时是即使延误也要休息10小时后再出发。
如果没有java concurrent api,那么就要使用java.util.Timer相关的API,比较繁琐。前者更简明。
如果用jmeter通过命令行(无图形界面)执行测试脚本,可参见jmeter最简单使用,并且启动多个jmeter实例,肯定会报地址端口已占用:
Waiting for possible shutdown message on port 4445
java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
这个配置在jmeter的bin目录下,找到jmeter.properties这部分:
# If running non-GUI, then JMeter listens on the following port for a shutdown message.
# To disable, set the port to 0.
#jmeterengine.nongui.port=4445
是用于监听shutdown message的,如果不需要,可以直接设置为0即可。
类似这样的代码:
InputStream inputStream = null;
try {
inputStream =file.getInputStream();
byte[] bs = new byte[inputStream.available()];
inputStream.read(bs);
File files = new File("a.log");OutputStream outputStream = new FileOutputStream(files);
outputStream.write(bs);
outputStream.close();
肯定是能工作的。但是,把输入流全部读入内存再写入文件流的做法,是不好的。如果是单机程序或者是随手写的小应用问题不大。在服务器端,用于对上传文件的处理,则会造成内存的较大抖动。对内存的时候完全依赖用户上传文件的大小。
目前需要测试一下文件上传业务模块的性能情况。用jmeter做测试。如果需要了解jmeter的简单使用,见jmeter最简单使用。
首先要确定要模拟的http post请求的链接和相关参数。比如,打开一个测试文件:
可以确定url是:
http://your_ip:port/context_path/your_action_path/uploadfile.do
然后,上传的文件参数名为files。
jmeter是apache jakarta项目下的测试工具,见:
可以用来做功能测试,负载测试和压力测试。是服务器端开发必备的测试工具。以前写过比较完整的文档,没有放在博客上,早就遗失了。最近做测试,要写多个日志记录基本的使用。
下载jmeter:
http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi
安装很简单,解压缩即可。jmeter是java编写的,因此要在运行jmeter之前确保已经安装jre。
运行jmeter,可以有图形方式和命令行方式。先说图形方式。在windows下:
双击jmeterw.cmd即可。
对用GridView实现Gallery的效果再做一个处理,假设图片加载是通过服务器端的,那么在没有加载完毕的时候界面上要有个ProgressBar显示,当加载完毕后,取消ProgressBar。
这里是示意性的代码,图片是一上来就加载了,实际情况应该是只看到ProgressBar。这里需要使用FrameLayout,它可以让多个视图重叠在一起。
在实现横向的类似Gallery的效果中做了实现Gallery的尝试,但是效果不好。使用的是TableLayout,出现了横向拖动图片的时候,因为有倾斜(轻微的竖向拖动),会整个列表竖向滚动。其实这个问题可以将TableRow中条目设置为clickable来解决。但是效果依然不好。
这次尝试通过GridView来解决问题,效果很好,见截图:
基本思路是:
在android异步加载ListView中的图片中使用异步方式加载的图片,当时要的急,写的很粗糙,是为每个图片加载一个线程来实现的。
可以用java concurrent很简明的实现类似功能,并且用到线程池。
java5开始,增加了concurrent api,用于并发处理。比如起多个线程并发从网络上下载图片,然后在本地显示。
这里写个简单的代码,来说明如何使用concurrent api提供的线程连接池。
运行结果类似这样:
start do 1 task …
>>main thread end.
start do 2 task …
start do 1 finished.
start do 3 task …
start do 2 finished.
start do 3 finished.
这里的task1到task3,都做的同样的事情,让它所属的线程休眠2000ms:
private static void doSomething(int id) {
System.out.println("start do " + id + " task …");
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("start do " + id + " finished.");
}