gpt4 book ai didi

java - 如何使用同步锁定整个类的方法?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:44:10 25 4
gpt4 key购买 nike

我知道当你想锁定方法只由一个线程执行时,你可以用 synchronized 关键字声明它。

关于类呢,如何在一个线程时提供对整个类对象的锁正在该类的实例上执行一些代码?

换句话说,当一个线程正在一个对象上执行一个方法时,其他线程不应该即使在同一类的不同实例上也允许执行相同的方法。

最佳答案

您在特定对象上进行同步,可以是某个指定的静态锁对象,也可以是类对象(当静态方法被声明为同步时会发生这种情况):

class X {
private static final Object lock = new Object();
public void oneAtATime() {
synchronized (lock) {
// Do stuff
}
}
}
class Y {
public void oneAtATime() {
synchronized (Y.class) {
// Do stuff
}
}
}

每个变体都有自己的优点和缺点;类上的锁定允许类之外的其他代码出于自身原因使用相同的锁(这允许它编排比您提供的同步更高级别的同步),而 static final Object lock 方法允许您通过将锁定字段设为私有(private)来禁止它(这样可以更轻松地推断锁定并避免您的代码死锁,因为其他人编写了错误的代码)。

您当然也可以使用来自 java.util.concurrent 的一些同步机制, 就像明确的 Lock s,它提供了对锁定的更多控制(ReentrantLock 目前在高争用情况下比隐式锁执行得更好)。


编辑:请注意,静态/全局锁不是一个好方法 - 它意味着曾经创建的类的每个实例基本上都将绑定(bind)到每个其他实例(除了使更难测试或阅读代码,会严重损害可伸缩性)。我假设你这样做是为了同步某种全局状态?在那种情况下,我会考虑将该全局/静态状态包装在一个类中,并实现每个实例的同步而不是全局同步。

而不是这样的:

class Z {
private static int state;
public void oneAtATime(){
synchronized (Z.class) {
state++;
}
}
}

这样做:

class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);

现在 foobar 仍然相互关联,但它们可以独立于 frobquux 工作>。

关于java - 如何使用同步锁定整个类的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3133244/

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