class Block{
     String userID;
     String content;
     ..........
}现在有很多个线程同时在往list里添加Block的实例,每个线程的userID不一样,比如Thread 1输出userID为a的Block,Thread 2输出userID为b的Block,以此类推。。,假设共有3个线程,每个线程输出100个Block,content就是数字,如何做到以交错的形式输出到一个list,比如 Block{"a","1"} Block{"b","1"} Block{"c","1"} Block{"a","2"} Block{"b","2"} Block{"c","2"} .....最重要的是在实际应用中,线程都不是同步进行的,而是可能有先后顺序,比如Thread 1正在输出100个对象里的第90个,此时Thread 2 启动开始输出对象,那么输出的结果应该是:Block{"a","1"}....Block{"a","90"} Block{"b","1"} Block{"a","91"} Block{"b","2"} ...

解决方案 »

  1.   


    如果你在乎的是结果list中的顺序,你可以在线程写入完成后一次性地排序list,达到你希望的顺序就可以了
      

  2.   


    重点不在线程,或者说一个list里就是放着这些对象,怎么把其中的元素交错排列,注意list可能中途是在增加元素的。。
      

  3.   


    写一个方法,提供针对静态数据list的排列。(对静态数据list,这个方法相信对你不难)每次往list中添加数据的时候,都调用这个方法一次。
      

  4.   

    使用TreeSet,能满足你的要求。
      

  5.   


    我现在要根据userID交错输出,这个排序怎么搞?另外这个list也是在不停地输出的,如果按你的思路,多个线程插入数据时候都对list进行操作,这里估计牵涉到同步问题。。
      

  6.   

    这个排序当然不能按照userId了假设来自同一个线程的记录有n个了
    用于排序的值为字符串 n+userId 如000a,0000b,0000c,001a,001b,001c,002a,002b,002c排序只针对已经插入的记录,线程只添加新纪录,不会有同步问题
      

  7.   

    是否可以考虑使用wait()和notify()来阻塞和唤醒线程的执行。
      

  8.   


    这个Block类是对实际应用的简化,如果仅仅内容是string就简单了,实际的内容是list,所以根本上还是要求根据UserID来交错位置
      

  9.   

    开一个线程就自动交错打印,而且还不同步,这个要求确实挺困难的。
    每个线程打印的时候,不直接打印数据,而是保存到一个缓存(如一个list),缓存有一定的数量,当达到数量时缓存排序,然后打印,因为不同步,所以这样的缓存也需要好几个来交替接收数据,每个缓存排序的时候,注意保证最先的记录是从上个缓存的最后一个记录的下一条交错数据
    不过好像也没法避免重复id连在一起被打印的问题,毕竟不同步,往缓存保存的时候,某些id可能数据比较多建议还是使用同步吧,这样每次把数据交替输出到一个队列,然后打印队列就可以了。
      

  10.   


    缓存这个思路可以不过如何把缓存list里的对象根据组id交错输出呢。。比如里面放的是Block{ "a ", "1 "}   Block{ "a ", "2 "}   Block{ "a ", "3 "}   Block{ "b ", "1 "}   Block{ "b ", "2 "}   Block{ "b ", "3"} Block{ "c ", "1 "}.... 输出是:Block{ "a ", "1 "}   Block{ "b ", "1 "}   Block{ "c ", "1 "}   Block{ "a ", "2 "}   Block{ "b ", "2 "}   Block{ "c ", "2 "} 和我上面的回复所说的,主要是根据userid交错,而不是后面的content
      

  11.   


    比如保存到缓存List
    List<Block> list;
    String[] ids = {"a", "b", "c"};
    int cnt = 0;
    Block[] block = list.toArray(new Block[0]);
    for (int i=0; i<block.length; i++) { //循环ids做交换排序
        String id = ids[(cnt++%ids.length)];
        if (block[i].getUserId().equals(id)) {
            continue;
        }
        boolean change = false;
        for (int j=i+1; j<block.length; j++) {
            if (block[j].getUserId().equasl(id)) {
                Block tmp = block[j];
                block[j] = block[i];
                block[i] = tmp;
                change = true;
                break;
            }
        }    if (! change) { //如果没发生交换,错开下个id
            if (ids[cnt%ids.length].equals(id)) {
                cnt++;
            }
        }
    }for (Block b : block) {
        System.out.println(b);
    }
      

  12.   

    问题解决
    round robin 轮询调度算法http://security.ctocio.com.cn/securitycomment/385/8082385.shtml实际上根据我的需求应该不是把list里的对象交错,而是先把对象交错的顺序弄好,然后放到list里所以实际上就是按userID分组,每组放到一个list里去,然后根据round robin算命法每次只从每个组里拿一个对象出来,这样子就避免了一个组里的对象太多占用了系统资源的问题这个算法其实核心很简单 i= (i+1) % n  ,i 是上一次选择的组,n是总共有多少组list 不过还是要感谢以上几位~