TT_*_*TT_ 4 java multithreading locking synchronized
请解释以下有关Hortsmann,Cornell(9版,第865页)中"Core Java"的同步块的说明:
Vector类的get和set方法是同步的,但这对我们没有帮助.
...
但是,我们可以劫持锁:Run Code Online (Sandbox Code Playgroud)public void transfer(Vector<Double> accounts, int from, int to, int amount) { synchronized (accounts) { accounts.set(from, accounts.get(from) - amount); accounts.set(to, accounts.get(to) + amount); } //... }
这种方法有效,但它完全取决于Vector类对其所有mutator方法使用内部锁的事实.
为什么同步依赖于上述事实?如果线程A拥有对帐户的锁定,则没有其他线程可以获取相同的锁定.它不依赖于Vector用于其mutator方法的锁.
我能够想到的唯一可能的解释是以下一个.让线程A拥有对账户的锁定.如果Vector对其set/get使用另一个锁,那么线程A必须获得一个额外的锁以继续进行set/get,这是不可能的(由于某个原因,一个线程可以同时保存2个不同的锁吗?).
这个解释对我来说看起来不合理,但我没有别的.我错过了什么?
如果线程A拥有对帐户的锁定,则没有其他线程可以获取相同的锁定.它不依赖于Vector用于其mutator方法的锁.
但是如果Vector使用一个完全不相关的锁来进行自己的同步,那么你的锁对象将毫无意义.这样的代码不会同步:
x.transfer(vector, 100, 100, 100); // uses your lock
vector.add(100); // uses Vector's own, unrelated lock
Run Code Online (Sandbox Code Playgroud)
如果您的所有代码都通过您自己的方法(使用您的锁),并且没有人直接访问vector的方法,那么您没问题.(但是你根本不需要使用Vector的内置同步,并且可以使用ArrayList).
这些锁只有在所有相关代码路径都使用它们时才有效.通常涉及多种方法,他们需要使用同一组锁来正确地"互相交谈".程序员应该确保这一点.
让线程A拥有对账户的锁定.如果Vector对其set/get使用另一个锁,那么线程A必须获得一个额外的锁以继续进行set/get,这是不可能的(由于某个原因,一个线程可以同时保存2个不同的锁吗?).
这不是不可能的,线程A可以容纳任意数量的锁.但是,在上面的访问模式中,线程A保持第一个锁是没有意义的,因为当线程B仅使用内置的Vector锁时,它甚至不会尝试锁定它.
归档时间: |
|
查看次数: |
1272 次 |
最近记录: |