连HDFS源码大神都会犯的错之线程泄露
Posted 西瓜老师爱大数据
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了连HDFS源码大神都会犯的错之线程泄露相关的知识,希望对你有一定的参考价值。
说到HDFS,大数据的同学肯定都会很熟悉,HDFS是Hadoop的一个核心模块。这个项目开源超10年了,在全世界都很流行,全世界的很多高手都在维护着这个项目。所以给很多同学造成感觉,这样的项目的代码是不会有问题的。其实大家错了,因为这个项目有几百万行代码,极其复杂。所以其实是有很多漏洞的,所以最近想写一系列的文章来调侃一下,当然我心底里很尊敬和佩服这些作者的,但是智者千虑,必有一失,有一些问题,连HDFS源码大神都会犯这些错,所以这些错误其实我们的很多同学也在犯,我把拿出来调侃一番,大家引以为戒。
接下来我从HDFS源码出截取一段代码。
try { | |
flushBuffer(); // flush from all upper layers | |
if (currentPacket != null) { | |
waitAndQueueCurrentPacket(); | |
} | |
if (bytesCurBlock != 0) { | |
// send an empty packet to mark the end of the block | |
currentPacket = createPacket(0, 0, bytesCurBlock, currentSeqno++); | |
currentPacket.lastPacketInBlock = true; | |
currentPacket.syncBlock = shouldSyncBlock; | |
} | |
flushInternal(); // flush all data to Datanodes | |
// get last block before destroying the streamer | |
ExtendedBlock lastBlock = streamer.getBlock(); | |
closeThreads(false);//关闭线程 | |
completeFile(lastBlock); | |
} catch (ClosedChannelException e) { | |
} finally { | |
closed = true; | |
} | |
} |
大家不用太清楚这段代码是干什么的,如果是老手,应该看到方法名大概能猜出来代码是干什么的。说到这儿的时候,不知道有没有同学看出来这段代码的问题在哪儿?
这句代码的问题出在这儿:
flushInternal(); | |
// get last block before destroying the streamer | |
ExtendedBlock lastBlock = streamer.getBlock(); | |
closeThreads(false); | |
completeFile(lastBlock); |
大家看到红色字体的代码了吗?见名知意,这个方法应该就是用来关闭线程的。但是大家想,这段代码之前还有一些IO的操作,大家知道IO操作是很容易出问题的,那么如果前面的IO操作出问题了,按照我们代码的意思,不就try catch 了吗,这样的话线程就没关闭了,就会造成线程泄露。
那怎么解决这个问题呢,其实也简单,把关闭线程的方法写到finally里就可以了。
各位同学,大家在写代码的时候也容易犯这错,注意积累。大家加油。
以上是关于连HDFS源码大神都会犯的错之线程泄露的主要内容,如果未能解决你的问题,请参考以下文章