在ArrayList上工作的两种方法的同步
我有Sum类、Creator类、Item类和Main。该造物主创造随机物品,并将它们添加到一个ArrayList这是在项目类。该求和类读取项目并总结所有的重量。在Main类中,我从多个线程Creator和Sum 开始。这两个类都实现了Runnable并覆盖了 run 方法。在创建 200 个项目后,将在控制台中打印。
如何同步这些方法?当我启动线程时,Sum 中的方法首先结束并返回权重 0,然后创建 40 000 个随机项目。我将创建项目,同时对它们的所有权重求和,最后返回创建的项目数量和所有项目的权重。
求和类方法:
@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");
}
回答
BlockingQueue
我建议使用BlockingQueue接口的实现,而不是ArrayList. ABlockingQueue是线程安全的。
引用 Javadoc:
BlockingQueue实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。然而,大量的Collection操作addAll,containsAll,retainAll而removeAll不一定原子除非在实现中另有规定执行。因此,例如,addAll(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 ...}
}
}