gpt4 book ai didi

java - 在同一个对象上同步两次

转载 作者:搜寻专家 更新时间:2023-11-01 02:24:01 27 4
gpt4 key购买 nike

我正在编写一个实用程序类来实现秒表的行为。这个类的一个重要特性是它被设计为线程安全的。我使用名为 lockprivate final 字段进行同步。类中的两个方法称为 resetstart,它们分别重置和启动秒表。它们被实现为:

public void reset() {
synchronized (lock) {
beginTime = 0;
lapIndex = 0;
}
}

public void start() {
synchronized (lock) {
if (beginTime == 0) {
beginTime = System.nanoTime();
laps[lapIndex++] = beginTime;
}
}
}

最近,我想添加一个名为 restart 的额外便捷方法,它将重置并启动秒表。我希望它表现得像一个原子操作,所以我的想法是将其实现为:

public void restart() {
synchronized(lock) {
reset();
start();
}
}

但是,resetstart 方法已经在 lock 上同步,因此调用 restart 会在同一个对象两次。会不会有什么问题?在同一对象上多次同步的行为是否定义明确?有必要吗?我已经运行了代码,因为它似乎 工作正常,但我担心我可能会遗漏一些多线程常见的微妙之处。

最佳答案

同步两次没有问题。该线程已经拥有监视器,因此额外的同步并没有真正起到多大作用。这是必要的,否则您的 restart() 方法可能会在调用 reset()start() 之间被另一个线程中断。

避免双重同步的一种方法是让 restart()reset()start() 同步然后委托(delegate)到非同步的内部方法。

public void reset() {
synchronized (lock) {
_reset();
}
}

public void start() {
synchronized (lock) {
_start();
}
}

public void restart() {
synchronized(lock) {
_reset();
_start();
}
}

private void _reset() {
beginTime = 0;
lapIndex = 0;
}

private void _start() {
if (beginTime == 0) {
beginTime = System.nanoTime();
laps[lapIndex++] = beginTime;
}
}

关于java - 在同一个对象上同步两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30265533/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com