FunTester Java 自定义 Once 方法保障单次执行

。 测试交流评论78字数 1704阅读模式

最近在继续学习 Go 语言的过程中,发现了一个比较神奇的的对象sync.Once,顾名思义,就是执行一次。官方定义的如下:Once是一个只执行一个动作的对象,看包名sync知道这是在并发使用场景。

基础使用方法如下:文章源自玩技e族-https://www.playezu.com/180555.html

// TestOnceSimple once对象简单测试
//  @Description: 
//  @param t
//
func TestOnceSimple(t *testing.T) {
var once sync.Once
for i := 0; i < 10; i++ {
go once.Do(func() {
log.Println("执行一次")
})
}
time.Sleep(time.Second)
}

for循环里面分别异步执行了 10 次,但是最终控制台展示如下:文章源自玩技e族-https://www.playezu.com/180555.html

=== RUN   TestOnceSimple
2022/06/19 16:39:08 执行一次
--- PASS: TestOnceSimple (1.00s)
PASS

目前使用到场景中就是在各种配置进行初始化的时候,以防止多个异步同时来执行初始化任务导致异常。比如说,我再使用 Redis 连接池的时候,首先需要初始化连接池,通常需要一个方法来完成这个过程,大部分时候需要显式调用,除非这个池对于我们项目来讲是基础的功能,程序启动的时候就需要初始化。文章源自玩技e族-https://www.playezu.com/180555.html

这个在我写 Java 的过程中,用到的 HTTP 的连接池和 MySQL 的连接池,而后者就属于需要用的时候的再初始化的场景。还有一种方式,我们可以使用 Java 单例模式中的懒汉式的解决这个问题。但是我们如果在测试过程中使用不同的对象池的时候,这种方式又显得比较死板不够灵活。文章源自玩技e族-https://www.playezu.com/180555.html

所以在平时处理这种情况的时候,通常我会使用synchronized或者java.util.concurrent.locks.ReentrantLockconcurrent包里面的工具类完成这个需求。具体代码可参考 Java 单例的懒汉式的实现以及我之前的文章。文章源自玩技e族-https://www.playezu.com/180555.html

之前我对照 Go 语言的go异步关键字写了Java 自定义异步功能实践,写了一个 Java 版本的fun异步关键字。这次我自然计划要抄一下sync.Once设计。文章源自玩技e族-https://www.playezu.com/180555.html

下面是我的经过自己尝试写了一个简版的:文章源自玩技e族-https://www.playezu.com/180555.html

static Vector<Integer> ones = new Vector<>();
static ReentrantLock lock = new ReentrantLock();
/**
* 线程安全单次执行,仿照Go语言的once方法
*
* @param v
*/
public static void once(Closure v) {
try {
lock.lock();
int code = v.hashCode();
if (!ones.contains(code)) {
ones.add(code);
v.call();
}
} catch (Exception e) {
logger.warn("once执行方法失败", e);
} finally {
lock.unlock();
}
}

下面是测试代码:文章源自玩技e族-https://www.playezu.com/180555.html

package com.okcoin.hickwall.presses
import com.okcoin.hickwall.presses.funtester.httpclient.FunHttp
class OnceTest extends FunHttp {
public static void main(String[] args) {
def test = {
output("FunTester")
}
10.times {
fun {
once(test)
}
}
}
}

控制台输出:文章源自玩技e族-https://www.playezu.com/180555.html

16:56:22 main 守护线程:Deamon开启!
16:56:22 F-1  FunTester
16:56:23 Deamon 异步线程池等待执行1次耗时:6 ms
16:56:23 Deamon 异步线程池关闭!

从上面内容我们看到,虽然异步执行了 10 次,但是只有一次真正执行了,实现了预期的需求。文章源自玩技e族-https://www.playezu.com/180555.html

Fun·BUG 挖掘机·性能征服者·头顶锅盖·Tester

  • 性能测试专题
  • Java、Groovy、Go、Python
  • 单测&白盒
  • FunTester 社群风采
  • 测试理论鸡汤
  • 接口功能测试专题
  • FunTester 视频专题
  • 案例分享:方案、BUG、爬虫
  • UI 自动化专题
  • 测试工具专题

阅读原文,跳转我的仓库地址

玩技站长微信
添加好友自动发送入群邀请
weinxin
rainbow-shownow
玩技官方公众号
官方微信公众号
weinxin
PLAYEZU
 
  • 版权提示:本站仅供存储任何法律责任由作者承担▷诈骗举报◁▷新闻不符◁▷我要投稿◁
    风险通知:非原创文章均为网络投稿真实性无法判断,侵权联系2523030730
    免责声明:内容来自用户上传发布或新闻客户端自媒体,切勿!切勿!切勿!添加联系方式以免受骗。
  • 原创转载:https://www.playezu.com/180555.html
    转载说明: 点我前往阅读>>>
匿名

发表评论

匿名网友
确定