我同步了下面的代码,但它会导致并发问题。
我知道这是由多线程引起的,我对 synchronized
关键字感到困惑。我预计 list.length
值为 100。我该如何修复它?
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ThreadA extends Thread {
private static byte[] lock = new byte[0];
private static final List<String> list = new ArrayList<String>();
@Override
public void run() {
System.out.println(list.size());
synchronized(lock) {
int size = list.size();
if( size == 0 ) return;
if(size >= 100) {
list.clear();
}
}
}
public void add(String s) {
list.add(s);
}
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
new ThreadA().start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized(lock) {
for(int m = 0; m < 100; m++) {
list.add(new Date().toLocaleString());
}
}
}
}).start();
}
System.out.println("LIST.SIZE:" + list.size());
}
}
最佳答案
两个问题:
println 访问
list
时无需同步,也无需等待线程完成。您将获得当时列表的值。无法保证线程的执行顺序。可能会发生所有
ThreadA
实例在匿名线程之前运行的情况,并且结果可能是一个明显大于 100 的值。
关于java - 为什么这个方法会导致并发问题呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17000739/