Java中的同步LinkedList

Java中的同步LinkedList,java,linked-list,synchronized,Java,Linked List,Synchronized,当我有两个LinkedList时,产品和价格在类的顶部声明。还有一些线程可以写入这个列表,我必须用互斥锁(synchronized)保护这个列表。以下内容正确吗?是否有更好的方法 public class Shop extends Thread { volatile LinkedList<String> product = new LinkedList<String>(); volatile LinkedList<Float> price = new

当我有两个LinkedList时,产品和价格在类的顶部声明。还有一些线程可以写入这个列表,我必须用互斥锁(synchronized)保护这个列表。以下内容正确吗?是否有更好的方法

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);
    }
   }
  }
}
公共类商店扩展线程{
volatile LinkedList product=new LinkedList();
易变LinkedList价格=新LinkedList();
公共类插入器扩展线程{
@凌驾
公开募捐{
同步(产品){
产品名称。添加(i1);
}
同步(价格){
价格。添加(i2);
}
}
}
}

用以下方法装饰您的
链接列表

volatile List product=Collections.synchronizedList(新的LinkedList()); 我没有什么意见

  • 我不明白易变的意思。。。它是一个引用类型 始终指向同一列表,即使添加/删除 列表中的元素。(这是一个可变列表)
  • 当1个线程要添加(product1,price1)和另一个线程添加时 (product2,price2),两个列表的顺序可能都不正确。e、 g
    Product={product1,product2}和Price={Price 2,Price 1}。你 可以在一个线程中添加睡眠,您将看到
  • 这里面的代码比较好

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

    同步了Inserter.class

    synchronized(Inserter.class){
       product.add(i1)
       price.add(i2)
    }
    
    在全局对象上同步。应用于插入器不是唯一执行操作的类的情况

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

    不,您的代码不正确。您正在使用单独的同步块更新单独的集合。这意味着,当新产品已经添加且价格尚未附加时,您可能会在数据不一致性方面失败。因此,如果其他线程执行以下操作:

    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);
        }
    }
    
    这段代码更好,但有点难看。更好的解决方案不是持有平行证书,而是创建一个同时持有产品和价格的特殊类别:

    class Deal {
        private final Product product;
        private final Price price;
        public Deal(Product product, Price price) { ... }
        .......
    }
    
    请注意类
    Deal
    是不可变的


    现在,您可以将其放入一个集合中,如果需要,可以将其同步。但最好使用一个可用的并发集合。它效率更高,而且不容易出错

    好的。但是任务说明它只允许在Inserter类中进行编辑。请注意,无论是否使用
    synchronizedList
    进行装饰,迭代列表时,您仍然必须同步。@user3302074不仅在写操作上,而且在其他操作(如
    remove
    )上。我可以同步run方法吗?您可以通过synchronized static在类级别(而不是实例级别)上同步。您在2中的答案是我的问题,必须按顺序排序。但是教授说我应该只在Inserter类中添加一个互斥。但这并不能解决问题。
    class Deal {
        private final Product product;
        private final Price price;
        public Deal(Product product, Price price) { ... }
        .......
    }