如果我有两种方法不能在一个 class 中同时发生在不同的线程上,如何锁定它?

if i have two methods that cannot happen simultaneously in one class on separate threads, how to lock it?

如果我有一个 class 有 2 个方法,比如 setAsetBsynchronized 但它们在同一个对象上不同步,我怎么办锁定它,这样如果 class 有两个实例,方法 setAsetB 就不能同时发生?

您仍然可以在您创建的 class 中的另一个对象上进行同步。

Object lock = new Object();

然后只在锁定对象上同步。

如果您想更深入地了解它,可以使用 util.concurrency 库。 检查信号量或锁存器,取决于你想用你的 setA 和 setB

做什么

在单个静态引用上同步它们。 private static final Object lock = new Object () 就可以了,Will 就可以 TheClass.class。

这也意味着没有两个线程可以同时调用 setA,即使没有人在调用 setB。如果这不可接受,您可以使用(静态)读写锁进行更细粒度的访问。 setA使用读锁,setB使用写锁;这意味着任意数量的线程都可以调用 setA,但只有一个线程可以调用 setB。您可能 希望反过来也成立,因为这很容易出现死锁。

多种方式。

1) 您可以同步方法:public synchronized void setA() 这样做意味着一次只能有一个线程进入该方法(好的和坏的)

2) 更好的解决方案是使用 ReentrantLock:

ReentrantLock lock = new ReentrantLock();
void public void setA() {
    lock.lock();
    try {
        //Do Something
    } 
    finally {
        lock.unlock();
    }
}

还有其他方法。 您可以查看 Java 并发教程: https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

另一个不错的帖子: http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/

祝你好运!

简而言之,您可以在两种方法的主体中使用一个 synchronized (lockObj) {...} 块,并使用相同的 lockObj 实例。

class MyClass {
    private final Object lock;

    public MyClass(Object lock) {
        this.lock = lock;
    }

    public void setA() {
        synchronized (lock) {
            //...
        }
    }
    public void setB() {
        synchronized (lock) {
            //...
        }
    }
}

注意事项:

  • 锁不需要是静态的。如何提供它取决于您的实现。但是如果您希望每个 MyClass 实例都必须使用 相同的 锁实例以防止线程同时执行它们的块。
  • 在这种情况下您不能使用同步方法,因为每个非静态 synchronized 方法都将在此实例的监视器上使用它。
  • 如果要访问其他实例成员,也不能使用static synchronized方法。