一缕阳光 2008-11-16 12:08
浏览 336
已采纳

关于Java进度条多线程调用问题,一个很实用的问题,希望熟悉多线程编程的高手看看

目前我在做一个C/S架构的Java应用,其中有一项查询操作非常耗时,可以增加个进度条以提高用户界面友好型.大体流程是这样的,在一个方法内
protected void action_queryButton()实行一个耗时的查询操作ArrayList alQuery = BuinessLogic.getQuery(); 此操作非常耗时,我把它抽出来放到一个线程中去做,具体是:先写个QueryDialog继承于JDialog,上面加入JProgressBar进度条,在初始化QueryDialog的过程中启动线程做费时查询,期间不断将查询进度消息返回给JDialogProgress中的 JProgressBar(这样用户可以看到进度条在不断刷新往前跑),最后查询结束,返回查询结果集alQuery(是一个ArrayList对象). 这一切都已实现,关键问题是当我启动线程执行费时查询操作时,主线程也继续往下执行,我的线程还没来得及返回结果集,主线程已经
将一个空引用赋给result了(ArrayList result = alQuery;)等我线程返回时,一切晚矣~~~主线程继续往下执行(当然会抛个空指针异常,呵呵)...我的最终目的也就没有达到.我的目的是让线程去执行费时操作,同时界面显示进度条不断刷新,等费时查询结束,进度条跑到100%,然后返回结果集给主线程下一行的ArrayList引用对象 result,这样我才算真正完成任务,事与愿违啊,线程启动后,主线程继续往下走,没有完成任务交接.实例伪代码我附上了,
protected ArrayList action_queryButton()
{ //主线程开始
.
.
.
.
// 新建查询对话框
QueryDialog queryDialog = new QueryDialog(topFrame, this.managerContext);

    // 打开对话框:注意,我开始启动费时查询线程了.线程start方法我封装在queryDialog.showDialog(queryParam, iFrame)方法里,具体代码这
    //里不提供了.
    if (queryDialog.showDialog(queryParam, iFrame) != queryDialog.OPTION_OK)
    {
        // 用户取消 或者 异常
        queryDialog.dispose();
        queryDialog = null;
        return;
    }
    /*获得查询参数:注意我上面开启了个线程,当线程还没结束,也就是说还没返回查询结果集时,主线程继续往下走,执行了下步操作调getQuery方法得到一个ArrayList空对象(因为此时线程没有走完,不可能返回真实查询结果),系统会抛个空指针*/
    ArrayList result = queryDialog.getQuery();
    setQueryManagerContext(tempParam);
    queryDialog.dispose();
    queryDialog = null;

  //
  .
  .
  .
  .
  return result;

}

我的解决方法是在开启查询线程后,让主线程停止不动,不让它往下走,等待查询结束QueryDialog对象返回查询结果集后,再让主线程继续下一步 ArrayList result = queryDialog.getQuery();这样,result就有值了,一切都OK. 请问谁有更好的解决办法? 如果不方便给出代码,说出思路也行,说错没关系,大家一起探讨共同进步嘛,呵呵.

  • 写回答

1条回答 默认 最新

  • yarao123 2008-11-16 20:55
    关注

    主线程MainThread 就是显示对话框的线程

    [code="java"]class MainThread {
    public int count= 0 /* 计数百分比 /
    public WorkRunnable workThread /
    工作线程 */

    public void progress() {
    while( true ) {
    sychronized( workThread.condition ) {
    if( count == 100 ) {
    break; /* 工作线程处理完毕 */
    }
    wait();
    }
    }

       ArrayList result = workThread.bl.getQuery(); 
       ……
       /* 此时result 应该不为空 */
    

    }
    }[/code]

    工作线程 WorkRunnable 做查询的线程
    [code="java"]class WorkRunnable implements Runnable {
    public BuinessLogic bl;
    public Object condition /* 用于主线程和工作线程同步 */
    public MainThread mt ;

    public void run() {
        String sqlstr = new String("select * …… " );
        ResultSet rs = conn.execute( sqlstr );
        while( rs.hasNext() ) {
            rs.next();
            ………
    
            /* 当前取的在总记录的百分比 */
            mt.count = 计算出的百分比;
            synchronized( condition ) {
                condition.notify();
            }
        }
    }
    

    }[/code]

    两个线程用一个condition进行同步,线程的同步主要依靠Object类的wait和notify方法来实现。5.0后有条件变量可以用

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试