看源码时的思考最近在看concurrent包下线程池的源码。看到ThreadPoolExecutor类的时候,发现JDK源码有问题。下面是ThreadPoolExecutor类的addWorker方法的代码段:booleanworkerStarted=false;booleanworkerAdded=false;Workerw=null;try{w=newWorker(firstTask);最终线程t=w.thread;if(t!=null){finalReentrantLockmainLock=this.mainLock;主锁.lock();尝试{intrs=runStateOf(ctl.get());if(rslargestPoolSize)largestPoolSize=s;添加的工人=真;}}最后{mainLock.unlock();}if(workerAdded){t.start();workerStarted=真;}}}finally{if(!workerStarted)addWorkerFailed(w);}returnworkerStarted;这段代码的功能完全没问题,但是如果使用guard语句,代码的可读性会更高。那么守卫声明是什么?什么是守卫声明?条件表达式通常有两种表现形式。第一种形式是:所有分支都属于正常行为;第二种形式是:条件表达式提供的答案只有一个是正常行为,其他都是不常见的。健康)状况。这两类条件表达式的用途不同,应该通过代码来表达。如果两个分支都是正常行为,则应使用if...else...形式的条件表达式;函数返回。这种单独的检查通常称为“保护条款”。光看枯燥的概念是很难理解的。让我们举两个例子。ConditionCheckReplacement这是一种计算员工工资的方法,其中外籍和退休员工按照特殊规则进行处理。这些情况不会经常发生,但偶尔会发生。publicdoublegetSalary(){双结果;if(this.isSeparated){//外籍员工result=this.separatedSalary();}else{if(this.isRetired){//退休员工result=this.retiredSalary();}else{//普通员工result=this.normalSalary();}}returnresult;}这段代码中异常情况的检查覆盖了正常情况的检查,所以应该用guard语句来代替这些条件检查,以提高程序的清晰度。对于每张支票,都放入警卫声明。guard语句要么从函数返回,要么抛出异常。publicdoublegetSalary(){if(this.isSeparated){//guard语句returnthis.separatedSalary();}if(this.isRetired){//守卫声明returnthis.retiredSalary();}returnthis.normalSalary();}反向条件替换这是求已知长宽高的长方体体积的方法,但是有一个特殊要求:当高度大于0时,打印万茂学社。(惊喜吗?意外吗?突兀吗?不正常吗?是的,有时候我们会收到这样的需求。)代码是这样的:publicdoublegetVolume(doublelength,doublewidth,doubleheight)结果=0.0;if(height>0.0){System.out.println("万猫学社");如果(长度>0.0&&宽度>0.0){结果=长度*宽度*高度;}}returnresult;}还是用guard语句代替条件检查,但是我们需要对相应的条件进行反转,即做逻辑NOT操作。publicdoublegetVolume(doublelength,doublewidth,doubleheight){if(height<=0.0){//Guardstatement,!(height>0)return0.0;}System.out.println("万猫学社");if(length<=0.0||width<=0.0){//保护语句,!(length>0&&width>0)return0.0;}returnlength*width*height;}为什么要用guard语句?守卫句的本质是:对某个分支给予特别关注。如果您使用if...else...结构,则您对if分支和else分支给予同等重视。这样的代码结构向读者传达的信息是每个分支都同等重要。警卫声明是不同的。它告诉读者:“这种情况很少见,如果真的发生,请做一些必要的清理工作并退出。”如果您对方法的其余部分不再感兴趣,您当然应该立即退出。将代码的读者引向无用的else块只会妨碍他们的理解。使用guard语句后,代码更容易理解和维护。优化JDK代码看了上面的解释,addWorker方法的代码片段可以优化如下:booleanworkerStarted=false;布尔workerAdded=false;工人w=null;尝试{w=newWorker(firstTask);最终线程t=w。线;if(t==null){//guard语句returnworkerStarted;}finalReentrantLockmainLock=this.mainLock;主锁.lock();尝试{intrs=runStateOf(ctl.get());//guard语句if(rs>SHUTDOWN||(rs==SHUTDOWN&&firstTask!=null)){returnworkerStarted;}if(t.isAlive())//预先检查t是否可启动thrownewIllegalThreadStateException();workers.add(w);ints=workers.size();如果(s>largestPoolSize)largestPoolSize=s;添加的工人=真;}最后{mainLock.unlock();}if(workerAdded){t.start();workerStarted=真;}}finally{if(!workerStarted)addWorkerFailed(w);}returnworkerStarted;修改后的代码,是否可以理解?更轻松?如果增加了新的功能,修改代码会更容易。结论这个JDK源码在功能上没有问题,架构设计的也很完美,但是我觉得在可读性上还是可以优化的。像这样嵌套条件表达式的代码在JDK源码中不止这些。可能是作者当时没有考虑使用guard语句,或者他没有我那么挑剔。希望大家在自己的编码过程中可以尝试使用guard语句来代替嵌套条件表达式,以提高代码的清晰度和可维护性。参考资料:《重构:改善既有代码的设计》