目前做的是一个工作流的程序,每一步结束就会向下一步的执行人发送短信,发短信的程序使用了线程,现在出现的问题是不定时会在某个环节,提交以后,会一直向下一执行人发送多达四五百条短信。我对线程不是特别熟悉,不知道是不是线程引起的问题,当服务器停止后,是不是没有结束的线程还会继续执行。请高手赐教!!

解决方案 »

  1.   

    先问几个问题,以便分析清况:
    1.是很快的连续发送短信吗? 还是超时重发?
    2.程序中是否有发送信息后确认发送成功?
    3.如果没有确认发送成功,是否有重发次数上限?需要查看一下代码,看具体是如何实现的。如果是连续发送短信,说明可能有BUG造成死循环。
    如果是超时重发,应有一个重发次数上限,如:重发3次还没有确认的话,应改用其它方法通知,如发email及发送报告到其它相关人。
      

  2.   

    每一步结束就会向下一步的执行人发送短信
    考虑多线程 
    生产者和消费者模式 生产者(每一步产生任务) 
    消费者(下一步处理业务:发短信) 给个例子  CSDN前辈牛人 ---axman -诗剑书生博客--非常值得收藏 http://blog.csdn.net/axman/default.aspx?PageNumber=8 
    Java code[生产者与消费者模式]  首先以一个生产者和消费者模式来进入实战篇的第一节。  生产者和消费者模式中保护的是谁?  多线程编程都在保护着某些对象,这些个对象是"紧俏资源",要被最大限度地利用,这也是采用多线程方式的理由。在生产者消费者模式中,我们要保护的是"仓库",在我下面的这个例子中,就是桌子(table)。  我这个例子的模式完全是生产者-消费者模式,但我换了个名字。厨师-食客模式,这个食堂中只有1张桌子,同时最多放10个盘子,现在有4个厨师做菜,每做好一盘就往桌子上放(生产者将产品往仓库中放),而有6个食客不停地吃(消费者消费产品,为了说明问题,他们的食量是无限的)。  一般而言,厨师200-400ms做出一盘菜,而食客要400-600ms吃完一盘。当桌子上放满了10个盘子后,所有厨师都不能再往桌子上放,而当桌子是没有盘子时,所有的食客都只好等待。  下面我们来设计这个程序:  因为我们不知道具体是什么菜,所以叫它food: class Food{}
      然后是桌子,因为它要有序地放而且要有序地取(不能两个食客同时争取第三盘菜),所以我们扩展LinkedList,或者你用聚合把一个LinkedList作为属性也能达到同样的目的,例子中我是用继承,从构造方法中传入一个可以放置的最大值。class Table extends java.util.LinkedList{
      int maxSize;
      public Table(int maxSize){
        this.maxSize = maxSize;
      }
    }
    现在我们要为它加两个方法,一是厨师往上面放菜的方法,一是食客从桌子上拿菜的方法。放菜:因为一张桌子由多个厨师放菜,所以厨师放菜的要被同步,如果桌子上已经有十盘菜了。所有厨师就要等待: public synchronized void putFood(Food f){
        while(this.size() >= this.maxSize){
          try{
            this.wait();
          }catch(Exception e){}
        }
        this.add(f);
        notifyAll();
      }拿菜:同上面,如果桌子上一盘菜也没有,所有食客都要等待: public synchronized Food getFood(){
        while(this.size() <= 0){
          try{
            this.wait();
          }catch(Exception e){}
        }
        Food f = (Food)this.removeFirst();
        notifyAll();
        return f;
      }
    厨师类:  由于多个厨师要往一张桌子上放菜,所以他们要操作的桌子应该是同一个对象,我们从构造方法中将桌子对象传进去以便控制在主线程中只产生一张桌子。厨师做菜要用一定的时候,我用在make方法中用sleep表示他要消耗和时候,用200加上200的随机数保证时间有200-400ms中。做好后就要往桌子上放。这里有一个非常重要的问题一定要注意,就是对什么范围同步的问题,因为产生竞争的是桌子,所以所有putFood是同步的,而我们不能把厨师自己做菜的时间也放在同步中,因为做菜是各自做的。同样食客吃菜的时候也不应该同步,只有从桌子中取菜的时候是竞争的,而具体吃的时候是各自在吃。所以厨师类的代码如下: class Chef extends Thread{
      Table t;
      Random r = new Random(12345);
      public Chef(Table t){
        this.t = t;
      }
      public void run(){
        while(true){
          Food f = make();
          t.putFood(f);
        }
      }
      private Food make(){    try{
          Thread.sleep(200+r.nextInt(200));
        }catch(Exception e){}
        return new Food();
      }
    }
    同理我们产生食客类的代码如下:class Eater extends Thread{
      Table t;
      Random r = new Random(54321);
      public Eater(Table t){
        this.t = t;
      }
      public void run(){
        while(true){
          Food f = t.getFood();
          eat(f);
        }
      }
      private void eat(Food f){
        
        try{
          Thread.sleep(400+r.nextInt(200));
        }catch(Exception e){}
      }
    }完整的程序在这儿:package debug;
    import java.util.regex.*;
    import java.util.*;
    class Food{}class Table extends LinkedList{
      int maxSize;
      public Table(int maxSize){
        this.maxSize = maxSize;
      }
      public synchronized void putFood(Food f){
        while(this.size() >= this.maxSize){
          try{
            this.wait();
          }catch(Exception e){}
        }
        this.add(f);
        notifyAll();
      }
      
      public synchronized Food getFood(){
        while(this.size() <= 0){
          try{
            this.wait();
          }catch(Exception e){}
        }
        Food f = (Food)this.removeFirst();
        notifyAll();
        return f;
      }
    }
    class Chef extends Thread{
      Table t;
      String name;
      Random r = new Random(12345);
      public Chef(String name,Table t){
        this.t = t;
        this.name = name;
      }
      public void run(){
        while(true){
          Food f = make();
          System.out.println(name+" put a Food:"+f);
          t.putFood(f);
        }
      }
      private Food make(){
        try{
          Thread.sleep(200+r.nextInt(200));
        }catch(Exception e){}
        return new Food();
      }
    }class Eater extends Thread{
      Table t;
      String name;
      Random r = new Random(54321);
      public Eater(String name,Table t){
        this.t = t;
        this.name = name;
      }
      public void run(){
        while(true){
          Food f = t.getFood();
          System.out.println(name+" get a Food:"+f);
          eat(f);
          
        }
      }
      private void eat(Food f){
        
        try{
          Thread.sleep(400+r.nextInt(200));
        }catch(Exception e){}
      }
    }
    public class Test {
        public static void main(String[] args) throws Exception{
          Table t = new Table(10);
          new Chef("Chef1",t).start();
          new Chef("Chef2",t).start();
          new Chef("Chef3",t).start();
          new Chef("Chef4",t).start();
          new Eater("Eater1",t).start();
          new Eater("Eater2",t).start();
          new Eater("Eater3",t).start();
          new Eater("Eater4",t).start();
          new Eater("Eater5",t).start();
          new Eater("Eater6",t).start();    }
    }
      

  3.   

    应该是工作流的处理逻辑方面出了问题。
    因为,问题是不定时出现的,
    而且,大部分时候下一执行人是只收一条提示短信的。逻辑方面,楼主仔细分析一下吧,有可能是某个地方疏忽了,造成死循环什么的。
    当向同一人发送大量短信的时候,楼主可以查一下当时CPU的使用率,
    如果一直是满负荷运转,应该推测是死循环,或连锁循环一直未退出。短信发送程序一般都会与发送队列,这个队列有的在内存中有的在数据库。
    如果队列中只有一条待发短信,而执行人收到4~500条短信,则是短信发送线程有逻辑错误(一般不会出现这种情况)
    如果队列中本身就有好多条执行人的短信,那么,应该是你工作流的处理逻辑方面有些问题了。