当前位置: 首页 > 面试题库 >

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

沈思博
2023-03-14
问题内容

我知道当您想锁定仅由一个线程执行的方法时,可以使用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方法允许您通过设置锁定字段来禁止使用它私有(这样可以更轻松地推断出锁定状态,避免由于其他人编写的错误代码而导致代码死锁)。

当然,您也可以使用from的一些同步机制java.util.concurrent,例如explicit
Locks,它提供了对锁定的更多控制(ReentrantLock当前在高竞争下比隐式锁定要好一些)。

编辑: 请注意,静态/全局锁并不是一个好方法-
这意味着曾经创建的类的每个实例实际上都会与其他每个实例绑定在一起(除了使测试或阅读代码变得更加困难之外,还可以严重损害可扩展性)。我假设您这样做是为了同步某种全局状态?在那种情况下,我会考虑将全局/静态状态包装在一个类中,并按实例而不是全局实现同步。

代替这样的事情:

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仍然相互联系,但是它们可以独立于frob和进行工作quux



 类似资料:
  • 如果我们有一个synchronized方法,在使用同一个对象时需要进行同步,那该怎么做呢? 例如,我们有一个 同步函数,如果所有参数在不同的调用中都不同,则可以并行执行,但如果调用 1 中的参数与调用 2 中的参数相同,则不能并行执行: 如果和同时调用函数,我们将如何停止这里的死锁? 我认为和是易失性的,或者基于和的哈希值进行同步,或者通过包含和的新对象进行同步。

  • 问题内容: Java教程说:“不可能在同一对象上两次调用同步方法。” 这对于静态方法意味着什么?由于静态方法没有关联的对象,所以synced关键字会锁定在类而不是对象上吗? 问题答案: 由于静态方法没有关联的对象, 所以synced关键字会锁定在类而不是对象上吗? 是。

  • 问题内容: 我的问题是我是否有类似以下代码: 现在,当多个线程要调用内部类方法时,它们将获取外部类对象或内部类对象的锁,并且如何修改该语句,以便我同步对外部类对象的访问/ 问题答案: 当多个线程要调用内部类方法时,它们将获取外部类对象的锁 没有。 或用于内部类对象 是。 以及如何修改该语句,以便我同步访问外部类对象/ 加: 在方法内部,但请注意,内部锁先于外部锁获取,如语法现在建议的那样。一致的锁

  • 问题内容: 我正在建模一个游戏,其中多个玩家(线程)同时移动。玩家当前所在位置的信息被存储两次:该玩家具有一个变量“ hostField”,该变量引用板上的一个字段,每个字段都有一个ArrayList,用于存储当前位于该字段的玩家。 我对拥有冗余信息的事实不是很满意,但是我发现如果不遍历大数据集就无法避免这种情况。 但是,当玩家从一个字段移到另一个字段时,我想确保(1)冗余信息保持链接(2)此刻没

  • 使用JPA乐观锁定,我们可以通过@Version字段控制一个数据库表是否同时被另一个事务更新,从而允许在数据库中存储可靠的数据。 如果Java应用程序只有一个CRUD服务负责数据库中的特定实体,我们也可以同步它的方法并管理信息在数据库中的存储顺序。 所以我的问题是,这些场景之间有什么区别?是否存在任何性能优势或者甚至是可遵循的最佳实践?

  • 本文向大家介绍java同步之如何写一个锁Lock,包括了java同步之如何写一个锁Lock的使用技巧和注意事项,需要的朋友参考一下 问题 (1)自己动手写一个锁需要哪些知识? (2)自己动手写一个锁到底有多简单? (3)自己能不能写出来一个完美的锁? 简介 本篇文章的目标一是自己动手写一个锁,这个锁的功能很简单,能进行正常的加锁、解锁操作。 本篇文章的目标二是通过自己动手写一个锁,能更好地理解后面