连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源码大神都会犯的错之线程泄露的主要内容,如果未能解决你的问题,请参考以下文章

Go 语言从新手到大神:每个人都会踩的五十个坑(转)

Android的Fragment错误,commit 执行了一次,执行第二次报错 ?

使用java时可能会犯的错误

设计老鸟也会犯的3个响应式设计错误

测试代码时你会犯的 11 个错误

电脑每次开机都会弹这个错误框