前言
LightDB是基于PostgreSQL的分布式关系型数据库,100%兼容PostgreSQL。LightDB的安装程序是Java编写,可以选择GUI安装,其中有丰富的界面展示,有回退上一步,也可以选择命令行(cmd)安装,根据命令提示来安装。
最近,有个小需求,背景:cmd安装下,到输入数据库密码时候,首先输入数据库的初始密码,再次输入确认密。确认密码需要和初始密码一致才可以继续下一步安装。
假如用户输入确认密码时候,忘记初始密码、或者输入初始密码多输入而自己不知道,那这样就要重新开始安装了。考虑到这种情况,重新优化设计:如果输入确认密码错误三次,那么重新输入初始密码。
之前代码
public boolean execute() throws Exception {
System.out.println("Please enter original password:");
Console console = System.console();
String originalPassword = null;
//校验初始密码
while (true) {
originalPassword = String.valueOf(console.readPassword());
//不通过校验,continue,最后通过后break
....
break;
}
logger.info("初始密码配置完成");
System.out.println("Please enter confirm password:");
//校验确认密码
while(true){
confirmPassword = String.valueOf(console.readPassword());
//不通过校验,continue,最后通过后break
...
break;
}
logger.info("确认密码配置完成");
return true;
}
修改代码
public boolean execute() throws Exception {
int tryConfirmCount = 0;
retry:
for(;;){
System.out.println("Please enter original password:");
Console console = System.console();
String originalPassword = null;
//校验初始密码
while (true) {
originalPassword = String.valueOf(console.readPassword());
//不通过校验,continue,最后通过后break
....
break;
}
logger.info("初始密码配置完成");
System.out.println("Please enter confirm password:");
//校验确认密码
while(true){
if(tryConfirmCount >=3){
continue retry;
}
confirmPassword = String.valueOf(console.readPassword());
//不通过校验,continue,最后通过后break
(...; ++tryConfirmCount; )
break;
}
break;
}
logger.info("确认密码配置完成");
return true;
}
总结
如果不使用Java retry:这种小trick,那么自己定义一个标志位,对标志位进行判断,来确定循环的走向,那么代码实现就不太优雅了。
其实笔者之前从事后端开发,还没有遇到这种需求。上面代码设计主要灵感来源于JDK源码线程池源码(ThreadPoolExecutor.java)
笔者这边截图使用openJDK11
在截图中,886行,你可以看到 retry:,其实你可以把它看成是对887行循环的标志。在895行进入内部的循环,判断线程池实际工作线程数(workerCountOf(c)) 是否大于线程池的核心线程数或者最大线程数。大于,就直接结束方法。
899行,使用CAS方法去增加线程池实际工作线程数(保证线程安全),成功,直接退出最外部循环(887行),如果失败,且线程池未关闭,(903行)直接从最外部(887行)循环开始重新执行。
这里就简单解释线程池,其实详细可以自己翻一翻源码。源码实现比较精炼,有时候会给你带来一些代码设计的灵感。如果你想使用线程池或者使用scheduledExecutorService ,可以看看Nacos源码。
写在最后
- retry就是一个标记,其下一行就是for循环,标记对这个for循环的操作continue/break处理点,功能类似于goto;
- 其实不用retry来使用这种语法,可以使用任意合法的字符,只不过因为JDK中使用retry,大家习惯称之为retry。
参考
java中retry的用法_小志的博客的博客-CSDN博客_java retry