有如下一个查询一个表的类
public void demo() {
OracleDB db = new OracleDB();
String sql="select * from aaa";
ResultSet rs = db.UseQuery(sql);
try {
while (rs.next()) {
String aaa01 = (rs.getString(1));
System.out.println(aaa01);
}
catch (SQLException e) {
e.printStackTrace();
}
}
我将这个demo()放到了5个线程里去处理,以提高遍历的速度,这就存在一个线程同步的问题,如果不加同步处理,会出现5个线程都对所有的结果进行遍历,预期的结果是5个线程交替对记录进行遍历,我做的同步处理如下:
public void demo() {
OracleDB db = new OracleDB();
String sql="select * from aaa";
ResultSet rs = db.UseQuery(sql);
try {
synchronized (rs) {
while (rs.next()) {
String aaa01 = (rs.getString(1));
System.out.println(aaa01);
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
可是问题依然存在,我实在不知道该怎么处理了,请高手帮忙!

解决方案 »

  1.   

    所有的线程都是执行select * from aaa ,个人感觉当然会出现对所有的结果进行遍历.
    你是不是想实现
    线程1查询记录1,6,11......
    线程1查询记录2,7,12......
    线程1查询记录3,8,13......
    线程1查询记录4,9,14......
    线程1查询记录5,10,15......
      

  2.   

    private ResultSet rs;
    public void demo() {
    OracleDB db = new OracleDB();
    String sql="select * from aaa";
    rs = db.UseQuery(sql);
             exe();
    }
    public void exe(){
        try {
    synchronized (rs) {
    while (rs.next()) {
    String aaa01 = (rs.getString(1));
    System.out.println(aaa01);
    }
    }
    catch (SQLException e) {
    e.printStackTrace();
    }}
      

  3.   

    我将这个demo()放到了5个线程里去处理,以提高遍历的速度,这就存在一个线程同步的问题,如果不加同步处理,会出现5个线程都对所有的结果进行遍历,预期的结果是5个线程交替对记录进行遍历.
    你的程序运行在多CPU的环境下吗?
      

  4.   

    含有demo方法的类,我不知道类名,所以就用QueryClass代替了。
    class QueryClass{
      public Vector qResults = new Vector();
      public void demo() {
       OracleDB db = new OracleDB();
       String sql="select * from aaa";
      ResultSet rs = db.UseQuery(sql);
       try {
       while (rs.next()) {
       String aaa01 = (rs.getString(1));
       qResults.add(aaa01);
       //System.out.println(aaa01);
       }
       catch (SQLException e) {
       e.printStackTrace();
       }
      }
      public proccessResults(){
        System.out.println(qResults.remove());
      }
    }
    class ProccessThread extends Thread {
      private QueryClass qClass ;
      public ProccessThread(QueryClass qClass){
        this.qClass=qClass;
      }
      public void run(){
        qClass.proccessResults();
      }
    }
    上面你要调用demo方法的那个方法里面。原来的代码应该是直接写
    QueryClass qc = .....;
    ......//得到QueryClass 的实例qc
    qc.demo();
    现在改成:
    QueryClass qc = .....;
    ......
    qc.demo();
    int tNum = 10 ;//tNum线程的数量
    for(int i=0;i<tNum;i++){
      new ProccessThread(qc).start();
    }以上代码,我还没有测试过,但是,大体思路已经给出了。
    效果应该出来了。
      

  5.   

    不是多CPU的环境下,我先试试你的代码
      

  6.   

    public void demo() {
    OracleDB db = new OracleDB();
    String sql="select * from aaa";
    ResultSet rs = db.UseQuery(sql);
    try {
    synchronized (rs) {
    while (rs.next()) {
    String aaa01 = (rs.getString(1));
    System.out.println(aaa01);
    }
    }
    catch (SQLException e) {
    e.printStackTrace();
    }
    }
    你把demo()放到一个线程里,5个线程分别去做ResultSet rs = db.UseQuery(sql);
    然后有5个不同的 rs,然后你又synchronized (rs) ,你5个线程分别synchronized自己的rs对象
    所以不能达到你的目的
      

  7.   

    bushuang() ,看了你的代码,觉得没什么变化,认为还是无法处理这个问题
      

  8.   

    preferme() ,我正在看你的代码,然后准备测试下,然后再告诉你结果
      

  9.   

    我个人认为楼主程序的问题有以下几点:
        1. 如果不考虑按顺序输出的情况,那么完全不需要进行同步。
        2. 你的函数分为5个线程来检索数据其实和用一个线程没有区别,因为你没有把数据进行分块。也就是说,你没有指定每个线程应该从哪条数据开始检索。比如有10000条数据,那么线程A检索0-2000,线程B检索2000-4000依此类推。那么你就得在启动线程是告诉线程你要从哪个数据开始检索。
        3. 考虑到按顺序输出的情况,那么你可以在方法上加锁,或者锁定this。在rs上加锁实际上不会起到作用。
      

  10.   

    上面的代码,我又改进了一下,因为,你举的例子一组只查询到了一个数据,所以,对查询的数据没有进行封装,现在,用HashMap对每组数据进行封装。其他的代码,还是不要变的。
    class QueryClass{
      public Vector qResults = new Vector();
      public void demo() {
       OracleDB db = new OracleDB();
       String sql="select * from aaa";
      ResultSet rs = db.UseQuery(sql);
       try {
       while (rs.next()) {
       String aaa01 = (rs.getString(1));
       String aaa02 = (rs.getString(2));
       //将查询的结果的每一组放到一个HashMap当中。然后添加到Vector当中去。
       HashMap hr = new HashMap();
       hr.set("aaa01",aaa01);
       hr.set("aaa02",aaa02);
       qResults.add(hr);
       //System.out.println(aaa01);
       }
       catch (SQLException e) {
      
       }
      }
      public proccessResults(){
        while (!qResults.isEmpty()) {
        // 在这里填写对数据的处理代码,qResults.remove(0)取出的是一个HashMap,用get方法得到数据,进行处理。
        HashMap result = qResults.remove(0);
        //下面的代码,可以删掉。
      try {
      Thread.sleep(50);
      } catch (Exception e) {
      }
       System.out.println(Thread.currentThread().getName() + "\t"+ result.get("aaa01")+"\t"+result.get("aaa02")); }
      }
    }
    //这回,你再试试,应该没什么问题了。
      

  11.   

    我晕,你把exe这个方法放到线程里面去处理
      

  12.   

    private ResultSet rs;
    public void exe() {
    OracleDB db = new OracleDB();
    String sql="select * from aaa";
    rs = db.UseQuery(sql);
             exe();
    }
    public void demo(){
        try {
    synchronized (rs) {
    while (rs.next()) {
    String aaa01 = (rs.getString(1));
    System.out.println(aaa01);
    }
    }
    catch (SQLException e) {
    e.printStackTrace();
    }}
    如果你非要放demo进去处理就这样....