首页 > 解决方案 > 对 ArrayList 起作用的两种方法的同步

问题描述

我有Sum类、Creator类、Item类和MainCreator创建随机项并将它们添加到Item类中的ArrayList 中。Sum类读取项目并对所有项目的权重求和。在Main类中,我从多个线程CreatorSum开始。这两个类都实现了Runnable并覆盖了 run 方法。在控制台中打印 200 个创建后的项目。

如何同步这些方法?当我启动线程时,Sum 中的方法首先结束并返回权重 0,然后创建者创建 40 000 个随机项。我将创建项目,同时对它们的所有权重求和,最后返回创建了多少项目以及所有项目的权重。

Sum 类方法:

@Override
    public synchronized void run() {

        for(Towar x: Towar.list){
            try {
                Thread.currentThread().wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            counter++;
            sum+=x.getWaga();
            if(counter%100==0){
                System.out.println("Sum of "+counter+" items");
            }
        }
        System.out.println("Total weight of Items: "+sum);
    }

创建者类方法:

@Override
    public void run() {
        reader=new Scanner(text);
        while(reader.hasNextLine()){
            counter++;
            String[] x=reader.nextLine().split("_");
            synchronized (Towar.getList()){
                Towar.add(new Towar(x[0], Integer.parseInt(x[1])));
                Towar.list.notify();
                if(counter%200==0){
                    System.out.println("Created "+counter+" items");
                }
            }

        }
        System.out.println("Created in total: "+counter+" items");
    }

标签: javamultithreadingarraylistsynchronizationrunnable

解决方案


BlockingQueue

我建议使用BlockingQueue接口的实现,而不是ArrayList. ABlockingQueue线程安全的

引用 Javadoc:

BlockingQueue实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。但是,除非在实现中另外指定,否则批量收集操作addAll、和不一定以原子方式执行。因此,例如,在仅在.containsAllretainAllremoveAlladdAll(c)c

示例代码

 class Producer implements Runnable {
   private final BlockingQueue queue;
   Producer(BlockingQueue q) { queue = q; }
   public void run() {
        reader=new Scanner(text);
        while(reader.hasNextLine()){
            counter++;
            String[] x=reader.nextLine().split("_");
            q.put(new Towar(x[0], Integer.parseInt(x[1])));
            if(counter%200==0){
              System.out.println("Created "+counter+" items");
            }
        }
        q.put(null);
        System.out.println("Created in total: "+counter+" items");
   }
 }

 class Consumer implements Runnable {
   private final BlockingQueue queue;
   Consumer(BlockingQueue q) { queue = q; }
   public void run() {
     long sum = 0;
     try {
       while (true) { 
          Towar x = (Towar)queue.take();
          if (x == null) return;
          counter++;
          sum+=x.getWaga();
          if(counter%100==0){
                System.out.println("Sum of "+counter+" items");
          }
       }
     } catch (InterruptedException ex) { ... handle ...}
   }
 }

推荐阅读