多个锁 - 在幕后

时间:2015-05-14 14:20:37

标签: java multithreading synchronized

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对象是A类的成员。

lock1和lock2与list1.add(5),list2.add(5)之间是否有任何关系,它们是lock1和lock2对象的成员吗?或者只是用它来做这个?。

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

如果我有许多像void insert1()这样的方法,也需要进行同步,而不是创建那么多的lock = new Object(); ?

1 个答案:

答案 0 :(得分:1)

synchronized(lock1)有一件事,只有一件事:它可以防止其他线程同时在同一个对象上同步。这就是全部。

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

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

因此,您指定了一个锁定对象(例如,示例中为lock1)。并确保您的程序中每个代码块更新list1甚至查看 list1在{{1阻止。

由于没有两个线程可以同时在同一个对象上同步,因此没有两个线程可以同时修改或使用synchronized(lock1){ ... }