如何使用同步锁定整个类的方法? [英] How to lock a method for a whole class using synchronized?

查看:187
本文介绍了如何使用同步锁定整个类的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道当您想锁定仅由一个线程执行的方法时,可以使用synchronized关键字声明该方法.

I know when you want to lock method to be executed by only one thread you declare it with synchronized keyword.

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

What about classes, how to provide a lock on an entire class of objects when a thread is executing some code on an instance of that class?

换句话说,当线程在对象上执行方法时,不应有其他线程 甚至可以在同一类的不同实例上执行相同的方法.

In other words, when a thread is executing a method on an object, no other thread should be allowed to execute the same method even on a different instance of the same class.

推荐答案

您在特定对象上进行同步,该对象可以是某些指定的静态锁对象,也可以是类对象(在声明静态方法被声明为同步时发生):

You synchronize on a specific object, either some designated static lock object, or the class object (which happens when static methods are declared to be 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方法使您可以通过禁止使用锁定字段是私有的(这样可以更轻松地推断出锁定状态,避免由于其他人编写的错误代码而导致代码死锁).

Each variant has its own pros and cons; locking on the class allows other code, outside of the class, to use the same lock for its own reasons (which allows it to orchestrate more high-level synchronization than what you provide) while the static final Object lock approach lets you prohibits it by making the lock field private (which makes it easier to reason about the locking and avoid your code from deadlocking because someone else wrote bad code).

您当然也可以使用

You could of course also use some synchronization mechanism from java.util.concurrent, like explicit Locks, which provide more control over locking (and ReentrantLock currently performs a little better than implicit locks under high contention).

请注意,静态/全局锁并不是一个好方法-这意味着曾经创建的类的每个实例实际上都会与其他所有实例绑定在一起(除了难以测试或阅读代码,可能会严重损害可伸缩性).我假设您这样做是为了同步某种全局状态?在那种情况下,我会考虑将全局/静态状态包装在类中,并按实例而不是全局地实现同步.

Note that static/global locks aren't a great way to go - it means every instance of the class ever created will essentially be tied to every other instance (which, aside from making it harder to test or read the code, can severely harm scalability). I assume you do this to synchronize some kind of global state? In that case, I'd consider wrapping that global/static state in a class instead, and implement synchronization per-instance rather than globally.

而不是像这样的东西:

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工作.

Now foo and bar are still tied to each other, but they can work independently from frob and quux.

这篇关于如何使用同步锁定整个类的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆