class Resource{
public Lock lock = new ReentrantLock();
public void A(){
lock.lock();
try{ .. }
finally{
lock.unlock();
}
}
public void B(){
lock.lock();
try{ .. }
finally{
lock.unlock();
}
}
public void C(){
... //Nothing to do with lock here
}
}
现在可以说我有3个线程T1, T2, T3
和一个名为Resource
的{{1}}实例。
运行的第一件事是resource
。现在,假设T1 calls resource.A()
花费了1500分钟,如果resource.A()
在第100分钟内致电T2
(这意味着resource.B()
的电话正在运行),会发生什么?
当我对T1
进行穿孔时,它是锁定了 object 还是锁定了 method ?
谢谢
答案 0 :(得分:1)
锁定是通过线程获得的。因此,如果一个线程X持有该锁,则其他线程要等到X释放它才能获得该锁。
在您的情况下,方法B在方法A释放锁之前无法获得该锁。
答案 1 :(得分:0)
运行的第一件事是T1调用
resource.a()
。现在,假设resource.a()
花费了1500分钟,如果T2在第100分钟内致电resource.b()
(这意味着T1的电话正在运行),会发生什么?
发生的事情是T2被阻塞,直到T1调用resource.b()
释放锁为止。在这种情况下,它将被阻止1400分钟。
当我执行
lock.lock()
时是锁定对象还是锁定方法?
都不是。
您没有锁定Resource
实例:
Resource
实例具有一个 intrinsic 锁...此处未使用。resource.c()
的其他线程不会被阻止。您实际上并未锁定方法。锁定在方法的内部中。因此,例如,方法a
或方法b
可以在调用lock.lock()
之前或之后释放它们。
您实际上所做的是您获得了ReentrantLock
对象的锁定。
在这种情况下,方法中的三分之二会使用锁定对象,因此您实际上会锁定这些方法的相关部分由不同线程调用。
但是,如果调用是由同一线程进行的(例如,如果a()
被调用为b()
),则第二个调用将不会被阻止。 (这就是“可重入”在本文中的意思。)
答案 2 :(得分:0)
是锁定对象还是锁定方法?
都不是。它锁定了对象的 intrinsic monitor 。
一个常见的菜鸟错误是认为,如果线程A在某个对象o上同步,那么其他线程将无法使用或修改对象o。那根本不是真的。线程A通过输入synchronized(o)
块来阻止的唯一事情是,它阻止了其他线程同时在同一对象上进行同步。
如果要确保一次只能有一个线程可以使用或修改一个对象,则必须确保将代码使用或修改的每个 位置都包装在{{1 }}在同一个对象上同步的块。
某些程序员更喜欢使用单独的私有锁对象:
synchronized
优点是,它使其他类无法使用保护您的类的私有数据的锁。