您的位置:首页 > 其它

ArrayList 的线程安全问题

2015-07-04 16:16 253 查看
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class ArrayListTest {

/**
* @param ArrayList
*            的线程安全问题
*
*            加锁解决异常 java.util.ConcurrentModificationException
*            和java.lang.IndexOutOfBoundsException
*/
public static void main(String[] args) {
List<Double> data0 = Collections
.synchronizedList(new ArrayList<Double>());

data0.add(1.0);
data0.add(4.0);
data0.add(5.0);
data0.add(8.0);

ForList tlist = new ForList(data0);
ListAddRemove Lar = new ListAddRemove(data0);

ForList2 tlist2 = new ForList2(data0);
IteratorAddRemove Iar = new IteratorAddRemove(data0);

Thread t1 = new Thread(tlist);
// list 循环方法: for (int i = 0; i < l; i++);

Thread t2 = new Thread(Lar);// list 加减元素;

Thread t3 = new Thread(tlist2);
// Iterator 循环方法:for (Double data : data0) ;

Thread t4 = new Thread(Iar);// Iterator 加减元素;

int set = 1;// 模式选择
switch (set) {
case 1:
t1.start();// list 循环方法
t2.start();// list 加减元素;
break;
case 2:
t3.start();// Iterator 循环方法
t4.start();// Iterator 加减元素;
break;
case 3:
t1.start();// list 循环方法
t4.start();// Iterator 加减元素;
break;
case 4:
t3.start();// Iterator 循环方法
t2.start();// list 加减元素;
break;
}

}

}

class ForList implements Runnable// extends Thread
{
/**
* list 循环方法
*
*/
public ForList(List<Double> data0) {
this.data0 = data0;
}

private List<Double> data0;

private int count = 100;

public void run() {
while (count > 0) {
count--;
synchronized (data0) {
int l = data0.size();
for (int i = 0; i < l; i++) {
Double data = data0.get(i);
System.out.println(Thread.currentThread().getName()
+ "data: " + data);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
System.out
.println("——————————————————————————————————————————————————————");
}
}
}
}

class ListAddRemove implements Runnable {

private List<Double> data0;

private int count = 1000;
double i = 9;

/**
* list 加减元素
*
*/
public ListAddRemove(List<Double> data0) {
this.data0 = data0;
}

public void run() {
while (count > 0) {
synchronized (data0) {
count--;
data0.remove(i - 1);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

synchronized (data0) {
data0.add(i);
i++;
}

}
}

}

class ForList2 implements Runnable// extends Thread
{
/**
* Iterator 循环方法
*
*/
public ForList2(List<Double> data0) {
this.data0 = data0;
}

private List<Double> data0;

private int count = 100;

public void run() {
while (count > 0) {
count--;
synchronized (data0) {
for (Double data : data0) {
System.out.println(Thread.currentThread().getName()
+ "data: " + data);
}

try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
System.out
.println("——————————————————————————————————————————————————————");
}
}
}
}

class IteratorAddRemove implements Runnable {

private List<Double> data0;

private int count = 1000;
double i = 9;

/**
*
* Iterator 加减元素
*/
public IteratorAddRemove(List<Double> data0) {
this.data0 = data0;
}

public void run() {
while (count > 0) {
ListIterator<Double> li = data0.listIterator();
count--;

synchronized (data0) {
while (li.hasNext()) {
double j = li.next();
if (i - 1 == j) {
li.remove();
}
}
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

synchronized (data0) {
li.add(i);
}
i++;

}
}
}


ArrayList 的方法是线程不安全的,使用不当就会产生异常 java.util.ConcurrentModificationException 和 java.lang.IndexOutOfBoundsException

针对list方法和Iterator方法的混合使用,测试发现加锁能有效防止两种异常的产生
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: