您的位置:首页 > 数据库

基于XML的数据库开发-6

2013-09-18 00:30 288 查看
    最新一直工作比较忙,一直木有空继续写这个数据库。

    今天主要解决的是数据读写移除的冲突问题。

    数据库设计的时候是按照内存数据库来构思的,所以所有的数据实际上都是保存在ArrayList中的。

    因此会出现如下的问题:

    -----------------------------------------

    线程1正在循环读取数据

     for(DataCell:dataList) {

          //TODO

     }

     此时线程2又对数据进行了删除操作

         dataList.remove(1)

    -----------------------------------------

    这个时候,JAVA就会报java.util.ConcurrentModificationException。

    针对上述情况,我们一般可能想到的对应方法是使用synchronized。

    synchronized(dataList) {

        for(DataCell:dataList) {

              //TODO

         }

    }

    synchronized(dataList) {

        dataList.remove(1)

    }

    这样的写法的确可以通过同步来控制,但是如果我有3个线程,其中2个线程

    只是循环读取数据, 如果使用如上写法,就会造成1个线程读取完毕,另外一个线程继续读取的现象。

     会影响读取的效率。

     回过头来仔细想一下,其实我们只是希望将add/remove和循环read的操作进行乎斥即可。

     即循环read的时候不能对dataList进行操作。而删除的时候也不能进行循环读写。

     按照上述的思想,我们可以有2个方法(不是很完美,但是能解决这个问题)

     方法1.规定只用使用foreach语法来循环调用这个数组。且不能中途推出循环

                 这样,我们就可以复写iretor,将hastnext认为是循环开始的触发函数,netx()为null的时候认为是循环结束的条件。

                 但是这样的规定比较固定,所以可能导致程序编写有很多限制.暂时没有使用这个方法.

 

                 示例代码如下:

 

class DataCellList extends ArrayList<Integer>{

boolean isCanRemove = false;

class myIteratorDector implements Iterator<Integer>{

public Iterator dectorIre;

public myIteratorDector(Iterator ite) {
dectorIre = ite;
}

@Override
public boolean hasNext() {
System.out.println("iterator hasnext");
return dectorIre.hasNext();
}

@Override
public Integer next() {
System.out.println("iterator next");
Integer nextV = (Integer) dectorIre.next();
return nextV;
}

@Override
public void remove() {
dectorIre.remove();
}

}

/**
*
*/
private static final long serialVersionUID = 1L;

public Iterator<Integer>iterator()  {
System.out.println("iterator");
return new myIteratorDector(super.iterator());
}
}


 

     方法2:增加2个接口来表示进入循环和退出循环,进入循环的时候,判断当前是否有remove的操作,如果有,就开始等待.  如果remove操作结束.接口继续作如下处理:循环计数器+1 循环结束的时候,调用退出循环接口,则循环计数器-1,然后确认是否有remove操作应为这个循环而在wait,如果有则激活remove处理.

      相关代码:

public class DataCellList extends ArrayList<DataCell>{
private int currentInLoop = 0;
private int currentInRemoving = 0;

private Object mWaitForLoopObj = new Object();
private Object mWaitForRemoveAddObj = new Object();

public void enterLooper() {

//DebugThread debugThread = new DebugThread();
//debugThread.start();

if(currentInRemoving != 0) {
try {
synchronized(mWaitForRemoveAddObj) {
mWaitForRemoveAddObj.wait();
}
} catch (InterruptedException e) {
LogUtil.e(TAG, "setRemovingFlag error" + e.toString());
}
}

currentInLoop++;
}

public void leaveLooper() {
currentInLoop--;

if(currentInLoop == 0) {
synchronized(mWaitForLoopObj) {
mWaitForLoopObj.notify();
}
}
}

public boolean add(DataCell data) {
data.setId(this.size());
setRemoveAddFlag();
boolean result = super.add(data);
clearRemoveAddFlag();

return result;
}

public DataCell remove(int index) {
//this method is fobbiden
setRemoveAddFlag();
DataCell result = super.remove(index);
clearRemoveAddFlag();
return result;
}

private void setRemoveAddFlag() {
if(currentInLoop != 0) {
try {
synchronized(mWaitForLoopObj) {
mWaitForLoopObj.wait();
}
} catch (InterruptedException e) {
LogUtil.e(TAG, "setRemovingFlag error" + e.toString());
}
}

currentInRemoving++;
}

private void clearRemoveAddFlag() {
currentInRemoving--;
if(currentInRemoving == 0) {
synchronized(mWaitForRemoveAddObj) {
mWaitForRemoveAddObj.notify();
}
}
}

}


 

                

                 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: