免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2125 | 回复: 0
打印 上一主题 下一主题

java中任务执行和线程停止 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-23 16:40 |只看该作者 |倒序浏览
java中任务执行和线程停止







想象一下这个场景,用户刚刚点了连击数据库后,忽然想起这个数据库没有启动,要等到默认的timeout(比如30秒后),连接才会停止,这时用户想立刻停止连接数据库的动作,怎么处理呢?

Java代码
  1. 1.public void run(final IProgressMonitor pm) throws InvocationTargetException {   
  2. 2.        pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);   
  3. 3.        try {   
  4. 4.            connector.connectdatabase();   
  5. 5.        }catch(Exception e){   
  6. 6.            LOG.error(e.getMessage(), e);         
  7. 7.        }finally {   
  8. 8.            pm.done();   
  9. 9.        }   
  10. 10.    }  
  11. public void run(final IProgressMonitor pm) throws InvocationTargetException {
  12.                 pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);
  13.                 try {
  14.                         connector.connectdatabase();
  15.                 }catch(Exception e){
  16.                         LOG.error(e.getMessage(), e);               
  17.         }finally {
  18.                         pm.done();
  19.                 }
  20.         }
复制代码
这是在一个线程里完成该任务,如果connectdatabase();非常慢的话,那么用户只能一直等
更好的做法是,让另外一个线程去处理连接动作,前台页面返回,让用户可以做别的事情,示意代码如下

Java代码
  1. 1.public void run(final IProgressMonitor pm) throws InvocationTargetException {   
  2. 2.        pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);   
  3. 3.            Thread thread = new Thread("Cancel progress"){   
  4. 4.                public void run() {   
  5. 5.                    connector.connectdatabase();   
  6. 6.                }   
  7. 7.            };   
  8. 8.        thread.start();   
  9. 9.           
  10. 10.        }catch(Exception e){   
  11. 11.            LOG.error(e.getMessage(), e);         
  12. 12.        }finally {   
  13. 13.            pm.done();   
  14. 14.        }   
  15. 15.    }  
  16. public void run(final IProgressMonitor pm) throws InvocationTargetException {
  17.                 pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);
  18.                         Thread thread = new Thread("Cancel progress"){
  19.                                 public void run() {
  20.                                         connector.connectdatabase();
  21.                                 }
  22.                         };
  23.                 thread.start();
  24.                
  25.                 }catch(Exception e){
  26.                         LOG.error(e.getMessage(), e);               
  27.         }finally {
  28.                         pm.done();
  29.                 }
  30.         }
复制代码
这时用户发现数据库没有启动,想在页面中点一下终止连接按钮停止连接,比如在eclipse的IRunnableWithProgress中,虽然可以监听用户点击按钮,但是这时run 方法的线程和叫做"Cancel progress"的线程已经没有什么关系了,无法通过监听户点击终止按钮而使"Cancel progress"线程停下,这时可以用下面的方法


Java代码
  1. 1.public void run(final IProgressMonitor pm) throws InvocationTargetException {   
  2. 2.        pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);   
  3. 3.        try {   
  4. 4.            Thread thread = new Thread("Cancel progress"){   
  5. 5.                public void run() {   
  6. 6.                    connector.connectdatabase();   
  7. 7.                }   
  8. 8.            };   
  9. 9.            thread.start();   
  10. 10.               
  11. 11.            while (true) {   
  12. 12.                if(pm == null){   
  13. 13.                    break;   
  14. 14.                }                  
  15. 15.                if(pm.isCanceled()){   
  16. 16.connector.gc();   
  17. 17.                    thread.interrupt();               
  18. 18.                    return;   
  19. 19.                }else{   
  20. 20.                    try {   
  21. 21.                        Thread.sleep(100);   
  22. 22.                    } catch (InterruptedException e) {   
  23. 23.                        LOG.error(e.getMessage(), e);   
  24. 24.                    }   
  25. 25.                }   
  26. 26.                if(connector.isFinish()){   
  27. 27.                    break;   
  28. 28.                }   
  29. 29.            }         
  30. 30.        }catch(Exception e){   
  31. 31.            LOG.error(e.getMessage(), e);         
  32. 32.        }finally {   
  33. 33.            pm.done();   
  34. 34.        }   
  35. 35.    }  
  36. public void run(final IProgressMonitor pm) throws InvocationTargetException {
  37.                 pm.beginTask(Messages.progressMetadata, IProgressMonitor.UNKNOWN);
  38.                 try {
  39.                         Thread thread = new Thread("Cancel progress"){
  40.                                 public void run() {
  41.                                         connector.connectdatabase();
  42.                                 }
  43.                         };
  44.                         thread.start();
  45.                        
  46.                         while (true) {
  47.                                 if(pm == null){
  48.                                         break;
  49.                                 }                               
  50.                                 if(pm.isCanceled()){
  51. connector.gc();
  52.                                         thread.interrupt();                               
  53.                                         return;
  54.                                 }else{
  55.                                         try {
  56.                                                 Thread.sleep(100);
  57.                                         } catch (InterruptedException e) {
  58.                                                 LOG.error(e.getMessage(), e);
  59.                                         }
  60.                                 }
  61.                                 if(connector.isFinish()){
  62.                                         break;
  63.                                 }
  64.                         }               
  65.                 }catch(Exception e){
  66.                         LOG.error(e.getMessage(), e);               
  67.         }finally {
  68.                         pm.done();
  69.                 }
  70.         }
复制代码
即在父线程中,启动子线程,正常流程是,父线程一直处于循环中,每次循环去判断子线程是否完成,(当然子线程完成后需要设置一下完成标志位),发现子线程结束后父线程继续往下执行.当用户点击取消按钮后(pm.isCanceled()是IRunnableWithProgress中监听用户点击取消按钮时的动作),父线程立刻跳出循环,并且将子线程处理一下(比如回收一些垃圾等),这样就可以达到目的了.另外重要的一点,父线程循环过程中记得sleep一下,给其他线程一些执行机会,节省cpu资源
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP