我有下面的示例代码(使用 Java),它将从多个线程访问。
public class ApplicationProducts {
private final List<Product> myAppProducts = Collections.synchronizedList(new ArrayList<>());
private String firstPositionProductName;
private int firstPositionProductAvailability;
public void updateProducts(List<Product> products) {
myAppProducts.addAll(products);
}
public boolean checkAndReplaceFirstProduct(Product product) {
synchronized(myAppProducts) {
if((product.getId()).equals(myAppProducts.get(0).getId())) {
//calculations goes here to derive the below details
firstPositionProductAVailability = 10;
firstPositionProductName = abc;
return true;
} else {
return false;
}
}
}
public boolean removeFirstProduct(Product product) {
synchronized(myAppProducts) {
if((product.getId()).equals(myAppProducts.get(0).getId()) &(firstPositionProductName.getId().equals(myAppProducts.get(0).getId())) {
myAppProducts.remove(0);
return true;
} else {
throw new IllegalStateException(" Lock taken by some other product : product can't be removed ");
}
}
}
}
我有以下疑问,请帮忙吗?
(1)上面的类线程安全吗?
(2) 我真的需要“myAppProducts”上的“同步”吗,因为我已经在检查某些条件,即从两个方法中删除“同步”后,该类是否是线程安全的? 一个重要的一点是,在我的应用程序中,每个线程首先调用 checkAndReplaceFirstProduct() ,如果结果为真(意味着获取了产品并进行了一些计算),然后只调用了removeFirstProduct()?
(3) 我是否还需要在 updateProducts() 中添加“同步”,这只是将更多产品附加到现有列表中?
(4) 我知道synchronizedList的迭代器应该是“同步” block 的一部分( https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedList(java.util.List) ,它是否需要锁(同步)来访问“synchronizedList.get(index)”方法(如上面所示)?
最佳答案
Is the above class thread safe ?
是的,看起来不错。但我会在访问 myAppProducts.get(0)
和 myAppProducts.remove(0)
之前添加一些检查(如果列表为空怎么办?)。
Do I really need 'synchronization' on 'myAppProducts' as I am already checking for some condition i.e., will this class be thread safe after removing 'synchronized' from both methods ?
是的,您根据代码设计这样做:
- 对于原子性:两种方法都有“check-then-act”语句 - 如果您删除同步,则
if
条件在您测试时可能为 true,但在您到达以下行 - 为了可见性:您将值分配给firstXxx变量,并可以从不同的线程读取它们 - 如果没有同步,读取的结果是不确定的。
Do I need to add 'synchronization' inside updateProducts() as well, which simply appends the more products to the existing list ?
没有同步 addAll
。
I know that synchronizedList's Iterator should be part of 'synchronized' block. Do I need to use a lock when calling 'synchronizedList.get(index)'?
不,你不需要,get
已经同步。
关于java - 多线程的synchronizedList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39830118/