R H*_*R H 2 java multithreading thread-safety thread-synchronization
如果有人能够帮助我找到方法同步和对象同步之间的不同之处的真实例子,那就太好了.
方法同步示例
public class MyClassExample {
private int i;
public synchronized void increment(){
i = i + 1;
}
}
Run Code Online (Sandbox Code Playgroud)
对象同步示例
public class MyClassExample {
private int i;
Object writeLock = new Object();
public void increment(){
synchronized(writeLock) {
i = i + 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
tl; dr - 外部同步打开你攻击(有意或无意),并强迫你锁定可能没有必要的检查.在这个答案的最底部还有一些讨厌的信息.
同步方法几乎完全相同(见下图)同步:
synchroinzed void foo() {
}
void foo() {
synchronized(this) {
}
}
Run Code Online (Sandbox Code Playgroud)
通过使方法本身不是synchronized,你允许自己锁定任何Object,而不仅仅是this.我个人会建议在内部同步Object,就像这样
private final Object foolock = new Object();
void foo() {
synchronzied(foolock) {
}
}
Run Code Online (Sandbox Code Playgroud)
原因是,如果你做了一个synchronized方法,它可以有效锁定this别人可以synchronize对你进行锁定并将你锁定Object!想象一下:
class FooDoer {
// removed! using synchronized methods instead
//final Object foolock = new Object();
synchronized void foo() {
}
}
// thread 1 - attacker
FooDoer f = new FooDoer();
globalMap.put("TheFoo",f);
synchronized(f) {
while(true); // haha!
}
// thread 2 - victim
FooDoer f = globalMap.get("TheFoo");
f.foo(); // locked, because Thread 1 has locked us out!
Run Code Online (Sandbox Code Playgroud)
它打开了拒绝服务攻击.这不好!通过使锁定为内部,您作为类的作者可以准确地控制谁可以锁定对象的哪些区域以及在什么条件下.
另一个问题是您可能没有受保护的数据进行检查.例如:
synchronized void foo() {
if(expensiveAccessCheck()) {
update();
}
}
void foo() {
if(expensiveAccessCheck()) {
synchronized(foolock) {
update();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当您坐在那里旋转车轮时,您不必让其他人等待.也许你正在从URL中删除数据然后进行更新.为什么让其他人都被锁定在数据之外?在这种情况下,较低的粒度更好.
现在你可能还记得我之前说的几乎相同.两者之间存在微小的微小差异.synchronized方法将烘焙指令以同步到字节码中的方法签名.这将使字节码缩短1个字节,因为它不需要进行额外的调用.这可能会产生很小的影响,因为方法字节码中的字节数是决定是否内联的因素之一.尽管有这个细节,我强烈建议将它们视为相同,因为这是一种微观优化,在生产环境中几乎不会发挥显着作用.当它们不相同时,将它称为相同是不完整的.
| 归档时间: |
|
| 查看次数: |
4922 次 |
| 最近记录: |