public class MessageUtils extends Thread{
private boolean flag = true;
public void run() {
while (this.flag) {
try {
Thread.sleep(300000L); //5分钟
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (true) {
autoValidator();
try {
Thread.sleep(300000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//靠线程每5分钟运行提交一次
public void autoValidator(){
//…………
if(condition1){
sendMessage(id,type);
}
else if(condition2){
sendMessage(id,type);
}
//…………
}
//手动提交
public static int sendMessage(String companyid, String type){
int result = 0;
//…………
return result;
}}线程每五分钟运行一次autoValidator(),由于有时候sendMessage()向接口提交的数据量比较大,在页面手动运行sendMessage时接口那边的状态值还没返回来如果恰巧线程又在运行,会出现重复提交数据的现象,想用synchronized来解决,怎么解决?
解决方案 »
- javax.el.ELResolver错误
- Tomcat 超级高手请进
- 江湖救急!关于新建某一信息时,判断是否存在。
- Struts2怎么配置
- 可以同时装sql server2000和mysql5.0.18吗?
- 请问各位高手这种在线听歌是怎么实现的
- 求助:如何实现这样的功能?
- 在线急等,关于两个server同用session的问题
- applet和SERVLET通信的问题,请高手赐教!
- 表单用enctype="multipart/form-data"二进制流形式提交的话,除了file,其他的表单控件应该用什么方法接收呢?
- There is no statement named user.getUser in this SqlMap.
- tomcat中lib文件下jar包问题
synchronized只是协调线程工作,线程本身并不知道什么数据被提交过,什么没有被提交,加上synchronize只能让线程等待手动执行的结束后线程才执行,但并没有终止线程继续执行,所以线程还是会重复提交数据
可以,但是相对就比较复杂些,要另外写个函数包装下,可以用一些标志位来进行控制。boolean[] flag = {false};checkAndSendMessage(...){
synchronized (flag) {
if (flag[0]) throw new RuntimeException("正在提交中");
flag[0] = true;
}
sendMessage(...);
flag[0] = false;
}
另外,3楼说的是有部分道理的,我相信你现在是靠提交后就清空提交数据这种做法,因此在串行化执行后不会发生重复提交;但需要注意控制的是:如果发生异常的情况下,是否会出现重复提交,或者漏了提交;比如偶发的网络连接中断啥的。
另,你的手动提交是直接调用static方法还是什么,直接调用static方法就不是操作相同的实例,因为static属于类而不是实例,而static方法加上synchronized就相当于单线程,因为是锁Class对象,这样,两个不同的用户就不能同时提交,也要一个人提交完后另一个人才能提交,这样,如果两个人处理的业务是相干的,互斥还可以理解,如果两个人处理的业务完全不相干,就会造成性能低下。
我是通过解析接口返回来的xml中的状态值来判断是否改变字段status的值从而判断是否已经向接口成功提交了数据,因此我觉得如果是线程同步的话应该不会出现重复提交了吧