Attachment to binary code - thread deadlock causes CPU to stay high

Keywords: network

Business background:
Convert the accessories of system A into binary and spread them to system B
Original code:

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("Close flow exception:"+e.getMessage());
			}
		}

Question:
Occasionally, the CPU of the server will rise by more than 100%. By analyzing the service, it is found that a thread of this method is always active and does not close
It's an epiphany, not every time
Solution:
1. Since the thread cannot be shut down, give it a multi-threaded writing method. Only one thread is created at a time for detection. If the thread does not shut down for one minute, it will be forced to shut down.
The thread is closed when querying, but the while loop is not over, and the CPU is still high
Through the log, it is found that numByteRead in the while loop has been = 0 for 10-20 minutes, and 21G log has been printed.....
2. Through the log analysis of the last attempt, it is found that if there is a problem with the network input.available()=0, the length of byte[] buf will be 0, and the while loop will read 0 bytes at a time, resulting in a while loop. Therefore, if we find a problem with the network, when input.available()=0, let the thread sleep for a second, and try to get it again. If we try 5 times or don't get it, it will be straight The code after modification is as follows:

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("Failed to get attachment");
			}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("Close flow exception:"+e.getMessage());
			}
		}
	}

Posted by twistisking on Thu, 05 Dec 2019 03:45:41 -0800