多线程同步,jdbc问题


有如下一个查询一个表的类
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();
}
}
可是问题依然存在,我实在不知道该怎么处理了,请高手帮忙!

28 个解决方案

#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


线程1查询记录1,6,11......
线程2查询记录2,7,12......
线程3查询记录3,8,13......
线程4查询记录4,9,14......
线程5查询记录5,10,15....

#3


对,是这个意思

#4


自己顶!!

#5


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();
}

}

#6


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


你的程序运行在多CPU的环境下吗?

#7


含有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();
}

以上代码,我还没有测试过,但是,大体思路已经给出了。
效果应该出来了。

#8


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

#9


谢谢,我先试下,然后再给回复

#10


弱弱的问下这么做有什么意义啊-_-!

#11


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对象
所以不能达到你的目的

#12


是啊 ,可是不知道该如何处理,所以才发帖求助的,我做这个处理是为了吧读出的数据做其他的处理,其他的处理时间长,所以要用多线程了

#13


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

#14


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

#15


关注中~~

#16


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

#17


纠正以下,刚才写了代码测试一下发现以上第3点我说错了。

#18


没什么意思!

#19


为什么要用多线程啊?
多线程的效率没有但线程高呢!

#20


上面的代码,我又改进了一下,因为,你举的例子一组只查询到了一个数据,所以,对查询的数据没有进行封装,现在,用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"));

}
  }
}
//这回,你再试试,应该没什么问题了。

#21


结贴了!

#22


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

#23


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进去处理就这样....

#24


顺序遍历效力是最高的!因为你需要每一条数据!你又不是查询!软件级的并行只是概念上离散化!

#25


想法挺好,这个例子不好

#26


有必要这样做么,这样做的速度会提高么?值得怀疑啊

#27


问题的关键是要分批取出数据后要做其他的处理,真正费时间的在处理上,所以要把数据分段处理

#28


mark
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告