多重锁 - 幕后

Multiple locks - Behind the scene

class A {

Object lock1 = new Object();
Object lock2 = new Object();

List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();

void insert1() {
    synchronized (lock1) {
        list1.add(5);
    }
}

void insert2() {
    synchronized (lock2) {
        list2.add(5);
    }
}

void firing() {
    for (int i = 0; i < 1000000; i++) {
        insert1();
        insert2();
    }
}

以上是部分代码,这里线程t1调用firing(),t2调用firing()。 我使用了 lock1 和 lock2,这样两个线程都不会等待释放锁。 我的问题是幕后发生了什么?

lock1 和 lock2 对象是 class A 的成员。

lock1和lock2与list1.add(5)、list2.add(5)有关系吗,他们也是lock1和lock2对象的成员吗?或者它只是用来代替这个?

当使用synchronized void insert1()和synchronized void insert2()或synchronized(this)时,void insert1()和void insert2()是classA的成员和class的锁A 被获取,这发生在幕后,但在上述情况下,创建两个对象只是为了获取不同的锁。

如果我有很多像 void insert1() 这样的方法也需要同步,那么我应该创建那么多 locks = new Object(); 怎么办? ?

synchronized(lock1)做一件事,只做一件事:防止其他线程同时在同一个对象上同步。就这些了。

以下是您使用它的方式和原因:

您有一个具有某种状态的对象(例如 list1),您希望通过调用 list1.add(...) 之类的方法来更新该对象(即更改其状态)。 synchronized 解决的问题是,像 list1.add() 这样的方法可能必须将对象置于临时的 无效状态 才能实现更新。您不希望任何线程能够查看 list1 的状态,而其他线程正在更新它。

因此,您指定一个锁定对象(例如,lock1 在您的示例中)。并且您确保 程序中更新 list1 甚至 查看 list1 的每个代码块 它在 synchronized(lock1){ ... } 块内。

由于没有两个线程可以同时同步同一个对象,因此没有两个线程可以同时修改或使用 list1