除了安德鲁·莱金(Andrew Lygin)提到的程序外,您的程序还有另一个错误。
设置
lock为
nullif
userId以前未见过,因为`putIfAbsent(…)不会返回新值,它会返回以前的值:
Lock lock = userLock.putIfAbsent(userId, new ReentrantLock());
改为这样做:
Lock lock = userLock.computeIfAbsent(userId, k -> new ReentrantLock());
computeIfAbsent(…)返回新值。另外,它的附带好处是,除非实际需要一个新的Lock对象,否则不创建该对象。(对@bowmore表示感谢)。
这个程序线程安全吗?
假设您已修复错误,我们仍然无法告知该程序。我们所能知道的是,您的UserManagement类的实例将不允许对同一方法的这三个方法中的任何一个进行重复调用userId。
是否使程序线程安全取决于您的使用方式。例如,您的代码不允许两个线程同时更新
userId,但是如果他们尝试,它将允许它们一个接一个地更新。您的代码将无法控制哪一个优先— *** 作系统会做到这一点。
您的锁定可能会阻止两个线程将用户记录保持为无效状态,但是它们会将其保持在正确的状态吗?这个问题的答案超出了您向我们展示的一门课的范围。
线程安全性不是可组合的属性。也就是说,完全使用线程安全类构建某些对象并不能保证整个对象都是线程安全的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)