在一个WEB工程中使用了 struts 
现在有这么一个要求: 某个 Action 中的一段代码要在一个特定的时间(该特定时间是可以设置的)只执行一次.该段代码以外的代码每次都要执行.且该 Action 是被高并发访问的.所以我不能使用 :synchronized (this) {
...
    }来进行同步.如果这样做了必然回导至访问的排队现象.
同时也不能使用 Timer (项目要求).
请问各位高手能否赐教一良策!
先谢谢了

解决方案 »

  1.   


    这个就有点不明白了,每天的10:30 分 0秒 0毫秒执行一次? 代码是放在action里的,如果此刻这个action没有被调用那代码还执行吗?
      

  2.   


    代码是放在action里的,要是在10:30 分 0秒 0毫秒这个action没有被调用怎么办?
      

  3.   

    看来你特定的这段代码和Action中其他的业务没什么具体关联
    既然要在一天特定时间跑一次(或几次),不用把代码放在Action中吧,写一个脚本,每天定时跑就好了
      

  4.   

    我的理解是一天只能执行一次,以这个特定时间点为分割点,在特定时间点内第一次调用此action时执行该代码,是不是?
      

  5.   

    那每次执行该段代码时判断是否可执行,判断可以根据某个变量来判断,该变量可以是一个boolean类型的值(该变量设为synchronized),true的时候可运行,运行完后设为false。运行一个后台线程,该后台线程每秒检测当前时间是否是时间点,若是则设置那个boolean值为true。
      

  6.   


    还是要使用 synchronized 方法啊!
    你的意思是:synchronized (this) {
            if(synchronizedBool){//synchronizedBool 为你所说的判断条件
                synchronizedBool = false;
                if(nowIsExcuteTime){//判断是否到了执行时间
                     ...//执行逻辑
                }
            }
            synchronizedBool = true;
    }
      

  7.   

    不是,action里面只要放如下代码:if(synchronizedBool){
                synchronizedBool = false;
     ..//执行逻辑
    }
    在另外一个后台线程内控制一个变量:class myThread extends Thread{
     static boolean synchronizedBool= true;
    public void run(){
       //判断时间点并设施synchronizedBool值
    }
    }
      

  8.   

    当然那个synchronizedBool变量放在何处应该可以自定。
      

  9.   


    void fun()
    {
        if(/*currentTime>=executeTime*/ && executedFlagBool==false)
        {
            //insert your operation here
            executedFlagBool=true;
        }
        else if(/*currentTime>=resetTime*/)
            executedFlagBool=false;
        return;
    }
      

  10.   

    然后在Action里把代码改成调用这个方法就行了
      

  11.   


    如果一个线程执行到 Sing1 处.该其它线程执行了!将又会导致.....
      

  12.   

    为什么不将这段 特殊的代码以出来 ,做为一个Thread 在那边定时的跑呢
      

  13.   


    public class BaseAction extends DispatchAction {    private SpecialOption option = new SpecialOption();    public ActionForward update(ActionMap map, ActionForm form, ServletHttpRequest request, ServletHttpResponse response){    }    public ActionForward add(ActionMap map, ActionForm form, ServletHttpRequest request, ServletHttpResponse response){
            synchronized (option) {// 同步option对象,而不是整个Action
                option.****方法
            }
        }    public ActionForward delete(ActionMap map, ActionForm form, ServletHttpRequest request, ServletHttpResponse response){    }
        
    }// 特殊功能类
    public class SpecialOption() {}或者你单独使用DispatchAction,把调用的方法单独独立出来,等到了时间直接调用那个方法
      

  14.   


    是的,忘记加一句了。synchronizedBool为一个Boolean对象。synchronized(synchronizedBool){
    if(synchronizedBool){ 
              //Sing1 
                synchronizedBool = false; 
    ..//执行逻辑 

    }
      

  15.   

    这是我写的测试代码,可以用的。
    import java.util.Date;
    class Knowing{
    public static Boolean i = true;
    public void start(){
    test t1=new test("t1");
    test t2=new test("t2");
    test t3=new test("t3");
    timer ti=new timer();
    t1.start();
    t2.start();
    t3.start();
    ti.start();
    }
    public static void main(String[] args){
    Knowing k=new Knowing();
    k.start();
    }

    class test extends Thread{
    String name="";
    public test(String name){
    this.name=name;
    }
    public void run(){
    while(true){
    synchronized (i){
    if(i){
    System.out.println(name+":Hello!"+new Date(System.currentTimeMillis()).toLocaleString());
    i=false;
    }
    }
    }
    }
    }
    class timer extends Thread{
    int count=0;
    public synchronized  void run(){
    while(true){
    try {
    Thread.sleep(1000);
    count++;
    if(count==2){
    i = true;
    count=0;
    }
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    }
    }
    }
    }
      

  16.   

    谢谢各位了!
    因为赶时间,也没在验证 rainsilence 和 zhou02607 的回复了!
    最后变通了一下!
    在最底层使用的 synchronized .
      

  17.   

    到时间则执行,过了时间则尽可能快的执行就写一个变量保存上次执行时间,运行到的时候判断
    (当前时间是否超过10:30 && 上次执行日期!=今天) 
    为真则执行
    程序是action的话可以考虑把上次执行时间用一个小文件保存下即可
    至于action的高并发访问,把整个需要互斥的代码块synchronized即可
      

  18.   

    那样每个调用了这个Action的用户都要排队等啊,建议你等有时间的时候还是再修改一下吧