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(); ?
答案 0 :(得分:1)
synchronized(lock1)
有一件事,只有一件事:它可以防止其他线程同时在同一个对象上同步。这就是全部。
以下是您使用它的方式和原因:
您有一个具有某种状态的对象(例如list1
),并且您希望通过调用list1.add(...)
之类的方法来更新对象(即更改其状态)。 synchronized
解决的问题是,像list1.add()
这样的方法可能必须将对象置于临时的无效状态才能实现更新。你不希望任何线程能够在list1的状态下看,而其他一些线程正在更新它。
因此,您指定了一个锁定对象(例如,示例中为lock1
)。并确保您的程序中每个代码块更新list1
甚至查看 list1
在{{1阻止。
由于没有两个线程可以同时在同一个对象上同步,因此没有两个线程可以同时修改或使用synchronized(lock1){ ... }
。