java - 对 ArrayList 起作用的两种方法的同步
问题描述
我有Sum类、Creator类、Item类和Main。Creator创建随机项并将它们添加到Item类中的ArrayList 中。Sum类读取项目并对所有项目的权重求和。在Main类中,我从多个线程Creator和Sum开始。这两个类都实现了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");
}
解决方案
BlockingQueue
我建议使用BlockingQueue
接口的实现,而不是ArrayList
. ABlockingQueue
是线程安全的。
引用 Javadoc:
BlockingQueue
实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。但是,除非在实现中另外指定,否则批量收集操作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 ...}
}
}
推荐阅读
- c# - C# 线程示例代码在没有锁的情况下工作
- angular - 从 postbuild 脚本读取 environment.ts 数据
- angular - Angular 2 和 SEO 元标记
- javascript - 套接字 io 在反应中进行大量重新渲染
- flutter - 两页表单 [Flutter]
- sql - 限制 PostgreSQL 最小时间间隔的结果行
- python - 如何确定训练数据集的块大小
- php - 使用 Devanagar Unicode 字符串时,Php preg_replace 替代品无法按预期工作
- excel - 引用工作表时,Excel VBA 不断返回带有“@”的公式
- performance - 性能:如何使用 Recyclerview 流畅地显示大文本