栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

锁定特定对象的Java线程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

锁定特定对象的Java线程

你的想法很好。这是简单/天真的版本,但是不太可能起作用:

public static void saveSomethingimportantToDatabase(Object theObjectIwantToSave) {    synchronized (theObjectIwantToSave) {        if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo pre        }        // Have to do a lot other saving stuff, because it either saves everything or nothing        commit() // pseudo pre to actually commit all my changes to the database.    }}

此代码将对象本身用作锁。但是它必须是 相同的 对象(即objectInThreadA ==
objectInThreadB)才能起作用。如果两个线程正在一个互为 副本 的对象上运行-例如,具有相同的“ id”,则您将需要同步整个方法:

    public static synchronized void saveSomethingimportantToDatabase(Object theObjectIwantToSave) ...

当然,这将大大减少并发性(使用该方法,吞吐量将一次下降至一个线程-避免使用)。

或者找到一种基于保存对象获取 相同 锁定对象的方法,例如这种方法:

private static final ConcurrentHashMap<Object, Object> LOCKS = new ConcurrentHashMap<Object, Object>();public static void saveSomethingimportantToDatabase(Object theObjectIwantToSave) {    synchronized (LOCKS.putIfAbsent(theObjectIwantToSave.getId(), new Object())) {        ....        }    LOCKS.remove(theObjectIwantToSave.getId()); // Clean up lock object to stop memory leak}

最后一个版本是推荐的版本:它将确保使用相同的锁定对象锁定共享相同“ id”的两个保存对象-
该方法

ConcurrentHashMap.putIfAbsent()
是线程安全的,因此“此方法将起作用”,并且仅要求该对象
objectInThreadA.getId().equals(objectInThreadB.getId())
才能正常工作。同样,
int
由于Java的autoboxing,getId()的数据类型可以是任何类型,包括原始类型(例如)。

如果为对象覆盖

equals()
hashpre()
,则可以使用对象本身代替
object.getId()
,这将是一种改进(感谢@TheCapn指出这一点)

此解决方案只能在一个JVM中使用。如果您的服务器是群集的,那么完全不同的球类运动和Java的锁定机制将无济于事。您将不得不使用集群锁定解决方案,这超出了此答案的范围。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/469929.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号