附件转成二进制码-线程死锁导致CPU居高不下

1 篇文章 0 订阅

业务背景:
把A系统的附件转换成二进制流传到B系统
原始代码:

private byte[] imgToByte(String path){
		URL u;
		BufferedInputStream input = null;
		ByteArrayOutputStream out = null;
		try {
			u = new URL(path);
			input = new BufferedInputStream(u.openStream());
			out = new ByteArrayOutputStream();
			byte[] buf = new byte[input.available()];
			int numByteRead = 0;
			while ((numByteRead=input.read(buf))!=-1){
				out.write(buf, 0, numByteRead);
			}
			byte[] data = out.toByteArray();
			return data;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}finally{
			try {
				out.close();
				input.close();
			} catch (IOException e) {
				throw new Exception("关闭流异常:"+e.getMessage());
			}
		}

问题:
偶尔会出现服务器CPU升高,超过100%,通过分析服务,查出这个方法有一个线程一直在活跃状态,不关闭
此状态是偶发现像,并非每次都是这样
解决方案:
1、既然出现了线程关闭不了,给它来一个多线程的写法,每次只创建一个线程,搞个检测,如果一分钟线程没有关闭,则强制关闭。
线程查的时候说是关闭了,但是while循环并没有结束,CPU还是高
通过日志,发现while循环里numByteRead一直=0,打印了10-20分钟,竟然打印了21G的日志。。。。。
2、通过上次尝试的日志分析,发现如果网络出现问题input.available()=0,byte[] buf的长度就会是0,while循环每次都去读0个字节,导致while死循环,于是,我们如果发现网络有问题,input.available()=0的时候,让线程睡一秒钟,再次尝试去获取,尝试5次还是没有取到,则直接抛异常,修改后的代码如下:

private byte[] imgByteFromImg(String path){
		URL u;
		BufferedInputStream input = null;
		ByteArrayOutputStream out = null;
		try {
			u = new URL(path);
			input = new BufferedInputStream(u.openStream());
			out = new ByteArrayOutputStream();
			int imgCount = input.available();
			int exeNum = 0;
			while(imgCount==0 && exeNum<5){
				Thread.sleep(1000);
				imgCount = input.available();
				exeNum = exeNum + 1;
			}
			log.info("exeNum==============="+exeNum);
			if(imgCount==0){
				throw new EshopException("获取附件失败");
			}else{
				byte[] buf = new byte[imgCount];
				int numByteRead = 0;
				while ((numByteRead=input.read(buf))!=-1){
					out.write(buf, 0, numByteRead);
				}
				byte[] data = out.toByteArray();
				return data;
			}
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}finally{
			try {
				out.close();
				input.close();
			} catch (IOException e) {
				throw new EshopException("关闭流异常:"+e.getMessage());
			}
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值