多个线程访问同一个共享资源
当一个资源被多个线程访问会出现如下问题:
问题出现在i++,该操作不是原子性的可以分解为三步:
1内存到寄存器
2寄存器自增
3返回到内存
线程需要抢到CPU才能运行,CPU分配的时间戳用完了进入阻塞状态,此时两个线程可能同时会访问size++,就会出现ArrayIndexOutOfBoundsException
解决方案: 在临界区加上synchronized 关键字,确保同一时刻只能有一个线程进入。
synchronized (this) {
if (size == len) {
dataElement = Arrays.copyOf(dataElement, len + (len >> 1));
}
dataElement[size++] = element;
}
代码如下:
public class ArrayList<E> {
private Object[] dataElement;
private int size;
public ArrayList(int length) {
dataElement = new Object[length];
}
public ArrayList() {
this(10);
}
public boolean add(E element) {
int len = dataElement.length;
if (size == len) {
dataElement = Arrays.copyOf(dataElement, len + (len >> 1));
}
dataElement[size++] = element;
return true;
}
public int size() {
return size;
}
@SuppressWarnings("unchecked")
public E get(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException("越界size=" +10+"\tindex="+ index);
}
return (E) dataElement[index];
}
}
public class TestArrayList {
public static void main(String[] args) {
//共享资源
ArrayList<Integer> list = new ArrayList<>();
System.out.println("Start");
//一份共享资源被多个线程使用
new Thread(()->{
for(;;){
list.add(1);
}
}).start();
new Thread(()->{
for(;;){
list.add(1);
}
}).start();
}
}
相关文章
了解千锋动态
关注千锋教育服务号
扫一扫快速进入
千锋移动端页面
扫码匿名提建议
直达CEO信箱