我有一个程序,不断轮询数据库以获取某些字段值的变化.它在后台运行,目前使用while(true)和sleep()方法来设置间隔.我想知道这是一个好习惯吗?而且,实现这一点可能是一种更有效的方法?该计划旨在始终运行.
因此,停止程序的唯一方法是对进程ID发出kill.该程序可能处于JDBC调用的中间.我怎么能更优雅地终止它呢?我知道最好的选择是通过使用将由线程定期检查的标志来设计某种退出策略.但是,我无法想到改变这个标志值的方式/条件.有任何想法吗?
我想知道这是一个好习惯吗?
不,这不好.有时候,这就是你所拥有的,但它并不好.
而且,实现这一点可能是一种更有效的方法?
事情如何首先进入数据库?
最好的改变是修复插入/更新数据库的程序,以发出进入数据库和程序的请求.JMS主题适用于此类事情.
下一个最佳更改是向数据库添加触发器,以将每个插入/更新事件排入队列.队列可以提供JMS主题(或队列)以供程序处理.
后备计划是您的轮询循环.
但是,您的轮询循环不应该轻松地完成工作.它应该将消息放入队列以供其他JDBC进程处理.终止请求是可以放入JMS队列的另一条消息.当程序获得终止消息时,绝对必须使用先前的JDBC请求完成并且可以正常停止.
在执行任何此操作之前,请查看ESB解决方案.Sun的JCAPS或TIBCO已经有了这个.像Mulesource或Jitterbit这样的开源ESB 可能已经构建并测试了这个功能.
在这种格式中完全回答这个问题确实太大了.帮自己一个忙,然后去实践中购买Java Concurrency.在Java 5+平台上没有更好的并发资源.有整个章节专门讨论这个问题.
关于在JDBC调用期间杀死进程的问题,这应该没问题.我相信中断JDBC调用存在问题(你不能这样做?)但这是一个不同的问题.
正如其他人所说,你必须进行民意调查的事实可能表明你的系统设计存在更深层次的问题......但有时这就是它的方式,所以...
如果你想更好地处理"杀死"这个过程,你可以安装一个关闭钩子,当你点击Ctrl+ 时调用它C:
volatile boolean stop = false; Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") { public void run() { stop = true; } });
然后定期检查停止变量.
更优雅的解决方案是等待一个事件:
boolean stop = false; final Object event = new Object(); Runtime.getRuntime().addShutdownHook(new Thread("shutdown thread") { public void run() { synchronized(event) { stop = true; event.notifyAll(); } } }); // ... and in your polling loop ... synchronized(event) { while(!stop) { // ... do JDBC access ... try { // Wait 30 seconds, but break out as soon as the event is fired. event.wait(30000); } catch(InterruptedException e) { // Log a message and exit. Never ignore interrupted exception. break; } } }
或类似的东西.