java 同步块 抛出异常_java – 抛出异常与同步

我有一个方法,许多线程并行访问,该方法使用一个具有两个我无法控制的同步方法的类. getObject和createNewObject.我想确保我不创建多个对象(MyObject).

MyObject obj;

public void method1() {

obj = getObject("key");

if (obj == null)

obj = createNewObject("key");

}

我认为这不会起作用,因为线程可以在获取和创建方法之间暂停,因此另一个线程也可以进入并创建一个对象.同步的createNewObject方法通过检查对象是否已存在名为“key”并在这种情况下抛出异常来解决此问题.

将优先考虑以下哪种方法?性能,安全性和设计明智.我听说双锁型(方法3)不起作用?也许我应该使用method1?

大多数时候,会找到对象,所以没有问题.在极少数情况下跳过同步并处理异常可能会有更好的性能吗?

MyObject obj;

public synchronized void method1() {

obj = getObject("key");

if (obj == null)

obj = createNewObject("key");

}

public void method2() {

obj = getObject("key");

if (obj == null)

try {

obj = createNewObject("key");

} catch (Exception e) { // ops, someone already created object "key"

obj = getObject();

}

}

public void method3() {

obj = getObject("key");

if (obj == null)

obj = getObj("key");

}

public synchronized MyObject getObj(String key) {

MyObject obj = getObject(key);

if (obj == null)

obj = createNewObject(key);

return obj;

}

解决方法:

这需要一些测试和分析,但我相当肯定你不会通过使用任何技巧获得任何重要的性能,因为在任何情况下都会执行同步,因为你每次都调用getObject()方法,这是同步的.所以这不是“同步/不同步”的那种差异,而是“同步/双同步”,这应该不是那么多.如果你正在进行同步,那么最好完全做到这一点.这意味着你的案例中的method1().

UPDATE

虽然method2()看起来也很有希望,但我刚刚意识到它有一个问题:因为它没有将写入同步到obj字段,所以其他线程可能看不到它的更新值.因此,如果obj字段由调用method2()的线程以外的其他线程访问,则method2()不正确.

如果你把obj字段设置为volatile,我相信它可能会工作(虽然不是100%肯定),因为getObject()是同步的,所以不应该有“对非易失性对象的易变引用”问题.在getObject()返回后,它会执行写入屏障,因此可以保证在主内存中存在完全初始化的对象.并且由于没有线程具有该对象的本地缓存副本,因此任何线程都可以访问obj字段.除非obj字段引用的对象是可变的,否则无论如何都应该同步对它的所有访问.

但这仍然没有多大意义.完全不同步的读取访问仍然是不可能的,因此干净的实现仍然比“智能”实现更好.

标签:java,exception,synchronized

来源: https://codeday.me/bug/20190713/1451849.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值