0

当使用两个线程时,如何确保打印顺序与原始数组中的顺序相同?我希望它打印“0 1 2 3 4 5 6 7 8 9”,但目前不能保证订单。有什么办法让它井井有条吗?十分感谢。

public class Test {
    public static void main(String[] args){
        DataStore dataStore = new DataStore();
        for(int i=0; i<10; i++){
            dataStore.add(String.valueOf(i));
        }
        CopyThread t1 = new CopyThread(dataStore);
        CopyThread t2 = new CopyThread(dataStore);
        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch(Throwable t) {
        }
    }   
}

class CopyThread extends Thread {
    private DataStore data; 

    public CopyThread(DataStore data){
        this.data = data;
    }
    public void run(){      
        DataStore.Line line = null;
        int lineID;

        while( (line = data.getLine()) != null ){       
            lineID = line.id;       
            System.out.println(Thread.currentThread().getName() + ": " + lineID);       
        }   
    }
}

class DataStore {
    ArrayList<String> lines = new ArrayList<String>();
    int current = 0;

    public synchronized Line getLine () {
        if (current >= lines.size()) {
            return null;
        }
        Line line = new Line(lines.get(current), current);
        current++;

        return line;
    }

    public synchronized void add (String s) {
        lines.add(s);
    }

    public synchronized int size () {
        return lines.size();
    }

    public static class Line {
        public String line;
        public int id;

        public Line (String str, int i) {
            line = str;
            id = i;
        }
    }
}
4

2 回答 2

1

尝试 Vector 而不是 ArrayList 。

向量

Vector 类实现了一个可增长的对象数组。像数组一样,它包含可以使用整数索引访问的组件。但是,Vector 的大小可以根据需要增加或缩小,以适应在创建 Vector 后添加和删除项目。

每个向量都试图通过维护容量和容量增量来优化存储管理。容量总是至少与向量大小一样大;它通常更大,因为随着组件被添加到向量中,向量的存储以块的形式增加容量增量的大小。应用程序可以在插入大量组件之前增加向量的容量;这减少了增量重新分配的数量。

Vector 的 iterator 和 listIterator 方法返回的 Iterator 是快速失败的:如果在创建 Iterator 后的任何时间对 Vector 进行结构修改,除了通过 Iterator 自己的 remove 或 add 方法之外的任何方式,Iterator 将抛出 ConcurrentModificationException。因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。Vector 的 elements 方法返回的枚举不是快速失败的。

请注意,不能保证迭代器的快速失败行为,因为一般来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。

于 2013-04-14T08:26:42.460 回答
0

您可以使用同步来实现:

synchronized(data) {
  while( (line = data.getLine()) != null ){       
        lineID = line.id;       
        System.out.println(Thread.currentThread().getName() + ": " + lineID);       
  }
}
于 2013-04-14T09:17:34.730 回答