java多线程访问ArrayList
我有一个用于缓冲数据的ArrayList,以便其他线程可以读取它们
这个数组不断地添加数据,因为它从udp源读取数据,而其他线程不断地从该数组读取数据。然后从数组中删除数据
这不是实际的代码,而是一个简化的示例:
public class PacketReader implements Runnable{
pubic static ArrayList<Packet> buffer = new ArrayList() ;
@Override
public void run(){
while(bActive){
//read from udp source and add data to the array
}
}
public class Player implements Runnable(){
@Override
public void run(){
//read packet from buffer
//decode packets
// now for the problem :
PacketReader.buffer.remove(the packet that's been read);
}
}
remove()方法从数组中移除数据包,然后将右侧的所有数据包向左移动以覆盖空白
我担心的是:由于缓冲区不断被多个线程添加和读取,remove()方法是否会因为必须将数据包向左移动而产生问题
我是说如果。add()或。get()方法在执行移位的同时被调用,这会有问题吗
我有时确实会遇到索引越界异常,它类似于: 索引:100大小300,这很奇怪,因为索引在大小范围内,所以我想知道这是否可能是导致问题的原因,或者我应该寻找其他问题
谢谢!
# 1 楼答案
是的,会有问题,因为ArrayList不是线程安全的,ArrayList对象的内部状态会被破坏,最终会出现一些不正确的输出或运行时异常。你可以尝试使用synchronizedList(List list),或者如果它很合适,你可以尝试使用CopyOnWriteArrayList
这个问题是Producer–consumer problem。你可以看到有多少人通过使用某种锁,轮流从缓冲区中提取一个对象(在你的例子中是一个列表)来修复它。如果不一定需要列表,也可以查看线程安全缓冲区实现