Java中的synchronized LinkedList

时间:2014-07-09 15:40:04

标签: java linked-list synchronized

当我有两个LinkedLists时,产品和价格在类的顶部声明。并且有一些线程可以写入此列表,我必须(!)使用互斥锁(同步)保护此列表。以下是否正确并且有更好的方法吗?

public class Shop extends Thread {
  volatile LinkedList<String> product = new LinkedList<String>();
  volatile LinkedList<Float> price = new LinkedList<Integer>();

  public class Inserter extends Thread {
   @Override
   public void run() {
    synchronized (product) {
     product.add(i1);
    }

    synchronized (price) {
     price.add(i2);
    }
   }
  }
}

3 个答案:

答案 0 :(得分:2)

使用Collections#synchronizedList装饰您的LinkedList

volatile List<String> product = Collections.synchronizedList(new LinkedList<String>());

答案 1 :(得分:0)

我的评论很少

  1. 我没有看到volatile的意思......它是一个参考类型 即使您添加/删除,也始终指向同一列表 列表中的元素。 (这是一个可变列表)
  2. 当1个线程想要添加(product1,price1)和另一个线程添加时 (product2,price2),两个列表的顺序可能出现故障。 e.g
    Product = {product1,product2}和Price = {price 2,price1}。您 可以在一个线程中添加一个睡眠,你会看到。
  3. 这里的代码更好

    synchronized (product) {
         product.add(i1);
         synchronized (price) {
             price.add(i2);
        }
    }
    

    2个想法

    同步Inserter.class

    synchronized(Inserter.class){
       product.add(i1)
       price.add(i2)
    }
    

    在全局对象上同步。适用于Inserter不是唯一一个进行操作的类。

    Object objLock = new Object()
    ...
    synchronized(objLock){
       product.add(i1)
       price.add(i2)
    }
    

答案 2 :(得分:0)

不,您的代码不正确。您正在使用单独的同步块来更新单独的集合。这意味着,如果尚未按价格添加新产品,则可能会导致数据失效。所以,如果其他线程做了这样的事情:

int n = product.size() -1;
Product prod = product.get(n); //OK
Price pr = price.get(n); // throws exception 

将抛出异常。

更好的解决方案是使用1个锁来同步两个操作:

Object productPriceLock = new Object(); 
.............

public void run() {
    synchronized (productPriceLock) {
        product.add(i1);
        price.add(i2);
    }
}

这段代码更好但有点难看。更好的解决方案不是保持平行的colecitons,而是创建一个既包含产品又包含价格的特殊类:

class Deal {
    private final Product product;
    private final Price price;
    public Deal(Product product, Price price) { ... }
    .......
}

请注意班级Deal是不可变的。

现在你可以把它放到一个集合中,如果你想同步它。但最好使用可用的并发集合之一。它更有效,更不容易出错。