我刚刚看完线程,说的可能有错哈。
建立一个继承thread的类Refresh,有一个刷新方法(此方法用来调用刷新程序)的计数器static count,初始值为0,每new Refresh(),count++。在main()方法中判断count数值是否小于3,小于则生成一个新的线程Refresh,并调用刷新方法,否则main线程sleep。当方法执行完毕,count--;这个就是thinking in java中的原例子。
import java.net.*;
import java.io.*;class JabberClientThread extends Thread {
  private Socket socket;
  private BufferedReader in;
  private PrintWriter out;
  private static int counter = 0;
  private int id = counter++;
  private static int threadcount = 0;
  public static int threadCount() { 
    return threadcount; 
  }
  public JabberClientThread(InetAddress addr) {
    System.out.println("Making client " + id);
    threadcount++;
    try {
      socket = 
        new Socket(addr, MultiJabberServer.PORT);
    } catch(IOException e) {
      System.err.println("Socket failed");
      // If the creation of the socket fails, 
      // nothing needs to be cleaned up.
    }
    try {    
      in = 
        new BufferedReader(
          new InputStreamReader(
            socket.getInputStream()));
      // Enable auto-flush:
      out = 
        new PrintWriter(
          new BufferedWriter(
            new OutputStreamWriter(
              socket.getOutputStream())), true);
      start();
    } catch(IOException e) {
      // The socket should be closed on any 
      // failures other than the socket 
      // constructor:
      try {
        socket.close();
      } catch(IOException e2) {
        System.err.println("Socket not closed");
      }
    }
    // Otherwise the socket will be closed by
    // the run() method of the thread.
  }
  public void run() {
    try {
      for(int i = 0; i < 25; i++) {
        out.println("Client " + id + ": " + i);
        String str = in.readLine();
        System.out.println(str);
      }
      out.println("END");
    } catch(IOException e) {
      System.err.println("IO Exception");
    } finally {
      // Always close it:
      try {
        socket.close();
      } catch(IOException e) {
        System.err.println("Socket not closed");
      }
      threadcount--; // Ending this thread
    }
  }
}public class MultiJabberClient {
  static final int MAX_THREADS = 40;
  public static void main(String[] args) 
      throws IOException, InterruptedException {
    InetAddress addr = 
      InetAddress.getByName(null);
    while(true) {
      if(JabberClientThread.threadCount() 
         < MAX_THREADS)
        new JabberClientThread(addr);
      Thread.currentThread().sleep(100);
    }
  }
}

解决方案 »

  1.   

    呵呵,没怎么看懂??什么模型,感觉蛮抽象的。能说得具体点吗?偶比较笨:)
    你要求实时性是否够高?如果不是很高的话,可以在调用程序的时候,通过读取文本文件的方式,即java去读一个文本文件,如果程序执行成功,则该程序把执行成功(比如说1)状态写入该文件,java读到后就认为是已经执行成功了。
      

  2.   

    需要考虑 模型,举个简单点的例子:前台页面显示20个对象的列表(list),20个对象里面放的是20个数字(如:1,2,3,9等);
    然后 后台有一个服务,就是根据你传入的参数,把它的值加到10000;但是,这个服务一台机子上只可以有 3个服务同时运行,就是说,1,2,3 在同时累加,直到10000。页面显示 1.2。3这3个对象的状态为 运行,9及其它为等待状态。如果(1,2,3)中有一个到了 10000,的时候,9就开始累加,依此类推
      

  3.   

    不需要考虑 模型,举个简单点的例子:前台页面显示20个对象的列表(list),20个对象里面放的是20个数字(如:1,2,3,9等);
    然后 后台有一个服务,就是根据你传入的参数,把它的值加到10000;但是,这个服务一台机子上只可以有 3个服务同时运行,就是说,1,2,3 在同时累加,直到10000。页面显示 1.2。3这3个对象的状态为 运行,9及其它为等待状态。如果(1,2,3)中有一个到了 10000,的时候,9就开始累加,依此类推
      

  4.   

    我似乎理解,如按我的理解能解决,我先确认一下:
    你想 只 开3个线程,用你的exe来提供service,然后顺序的把list里的20个对象都处理掉?
    是不是这样?
      

  5.   

    我确定, gemouzhi(gemouzhi) 
    我想 只 开3个线程,用的一个exe来提供service,然后顺序的把list里的20个对象用这3个线程都处理掉,
    是这样?
      

  6.   

    还得问一句:你那个exe自己能改吗?
      

  7.   

    .exe不能改啊 是别人写的,根本没办法返回值~~
      

  8.   

    你得和我说说exe的情况啊。
    1,如能更改exe是最好的,在exe结束运行的时候,写一个持久化的物件,然后线程循环加sleep的hunt这个持久化的物件就可以了。但你的exe不能更改。
    2,我不知道你exe是基于GUI的还是基于console的??3,如果基于console的,有没有输出?能用subprocess和process通信
    或用最简单的waitfor应该就能解决4,如果你是GUI的,你得给我描述GUI是如何显示的?用到什么控件?
    这个也能解决可以再用一个中介exe,这个是很好解决的。5,或者你的exe是不是能产生什么持久化的物件??我没有任何信息,没办法帮你。
      

  9.   

    使用线程控制进程,只能waitFor了
    然后根据exitValue判断是否正常退出
    如果不是正常退出,又怎么处理?
      

  10.   

    别人写的vb.exe 不能修改,没有返回值,不能往控制台打消息。
    只剩下持久化一个方法了,能往xml写东西,但是,我没办法判断是哪个线程执行的结果啊~~那个.exe能得到执行它的进程号,java又没有什么方法得到进程号!
    这也是最痛苦得地方。  本来想的是:当时想的是写一个有3线程的池,取线程的时候,处于就让等待状态(取的方法如果没有空先就sleep()然后,递归,直到有线程返回。clint客户端在调用时 默认初始状态是等待,当得到后执行start,状态改为运行状态。然后
    thread.start();
           // System.out.println("------thread.isAlive----------"+thread.isAlive());
            boolean a=true;
            while(a){
              if(!thread.isAlive()){
                a=false;
              }
            }
    //是否结束
            if(a==false){System.out.println("hahahahah");
    //运行完毕后,释放当前线程(线程状态为空闲)。
              service.release(thread);
            }
     执行释放返回执行完毕(不管成功,还是失败)。但是行不通~~真是郁闷啊,周二就要交东西,可是给这么个难题,怎么交啊~~
      

  11.   

    我想了解 waitFor 是什么意思?treeroot(旗鲁特) 如果不是正常退出,又怎么处理?  那现在只能不管成功失败 了,只是提示“执行结束”了否则只能想办法不停去.exe(vb)写的xml中查当前这个进程号的对应的执行结果了,可是进程号java怎么取啊?那个写.exe的老员工说了:就是不能往控制台 打消息(process通信想法不行)。
      

  12.   

    只要那个进程可以自己kill自己就行了,下面是一个建议,你参考一下import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    public class ProcessSyn {
        public static List models=Collections.synchronizedList(new ArrayList());
        private static Object lock=new Object(); //用来同步

    private ThreadGroup tg=new ThreadGroup("Test");
    private int MAX_PROCESSES=3;
    public void process(){

    while(!models.isEmpty()){
    if(tg.activeCount()>=MAX_PROCESSES){
    //阻塞,避免不必要的循环而占用CPU
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    if(tg.activeCount()<MAX_PROCESSES){
    new Thread(this.tg,new ThreadSyn((Model)models.get(0))).start();
    models.remove(0);
    }
    }
    } public static void main(String[] args){
    for(int i=0;i<20;i++){
    models.add(new Model(i));
    }
    new ProcessSyn().process();
    new Thread(new ThreadSyn(new Model(2))).start();
    }


    static class ThreadSyn implements Runnable{
    private Model model;
    public ThreadSyn(Model model){
    this.model=model;
    }
    public void run(){

    try {
    System.out.println(model.i+" start");//for test
    Process p=Runtime.getRuntime().exec("cmd /Cset");//这个进程必须自己消亡,否则一直线程会一直阻塞。
    p.waitFor();
    System.out.println(model.i+" end");//for test
    lock.notify();//可以加入新的线程了
    } catch (IOException e) {
    e.printStackTrace();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    class Model{
    Model(int i){this.i=i;}
    int i;
    }
      

  13.   

    哈哈 谢谢 treeroot(旗鲁特) 
    有几点我不太明白:
    1。我想问问Mode的作用是什么?
    2。public static void main(String[] args){
    for(int i=0;i<20;i++){
    models.add(new Model(i));
    }
    new ProcessSyn().process();
    new Thread(new ThreadSyn(new Model(2))).start();
    }
       这个20怎么才能动态的从前台页面取?(list中)。因为不够20的话用户可以再添加,所以20是最大值。但是20个以下的话用户就可以添加,就要从前台取。这样的话怎么解决好一点?我愿来做的是:当用户往 list中添加的时候,就去执行new ProcessSyn().process();不过我的new ProcessSyn().process()方法取一个线程出来,取不出来(全忙够3个线程同时运行),就一直等待-------不知道这样考虑有问题没
      

  14.   

    用户点击每个页面上 模型 时的添加:--》执行action--》执行service的下面这个方法:
    public List addMdlFlesh(List appList, Object obj) throws Exception {
        log.info("enter SchedulerRunListService addMdlFlesh.......");
        RunService service=RunService.getInstance();;
        ThreadRefresh thread=null;
        try {
          SchedulerRunForm runMdl = (SchedulerRunForm) obj;      thread= service.process();
          if(thread!=null){
            System.out.println("---thread is ---"+thread);
            //thread.SetParam(runMdl.getMdlFleshParam());
            thread.SetParam(" A_test@短信业务鉴权_日、周@F");
            thread.setUpdMdlExeUrl("D:/misc-report/广东/cubeManage/UpdateMdl ");
            thread.start();
           // System.out.println("------thread.isAlive----------"+thread.isAlive());
            boolean a=true;
            while(a){
              if(!thread.isAlive()){
                a=false;
              }
            }
            if(a==false){System.out.println("hahahahah");
              service.release(thread);
            }       // System.out.println(Thread.currentThread().toString());
           System.out.println("----------------------7777777777----");
          }else{      System.out.println("---thread is null---");
          }
        }
        catch (Exception e) {
          System.out.println("exception)))))))))))))---"+e.getMessage());
          log.error(e.getMessage());
          throw e;
        }
    //    finally{
    //      System.out.println(">>>>>>>>addMdlFlesh----释放---<<<<<<<<<");
    //      service.release(thread);
    //
    //    }
        return appList;
      }
    下面是 池管理:public class RunService{  private static Log log = LogFactory.getLog(RunService.class);
      //构造函数
      private  RunService() {
        this.parseXML();
        this.init();
      }
      //保证只有一个实例
      private static RunService instance = null;
      public static synchronized RunService getInstance() {
        if(instance==null){
          instance = new RunService();
        }
        return instance;
      }
      //可以同时运行的个数
      public int refreshNum= -1;
      //模型最多个数
      public int mdlNum=-1;
      //运行的线程数
      public int count=-1;
      //空闲数
      public int free=-1;
      //忙
      public int busy=-1;
      //存线程的地方
      public  Set threadPool;
    //初始化
      public void init(){
        //第一次空闲 线程最大个数
        free=this.refreshNum;
        //线程数为 线程最大个数
        count=0;
        threadPool=new HashSet();
        for(int i=0;i<this.refreshNum;i++){
         threadPool.add(new ThreadRefresh());
        }
      }
      //解析xml得到 线程最大个数(同时运行个数)
      private void parseXML() {
        try {
          SAXBuilder sb = new SAXBuilder(false);
          String Server = null;
          Document doc = sb.build(getClass().getResourceAsStream("/mdlRefresh.xml"));
          Element root = doc.getRootElement();
          this.refreshNum = Integer.parseInt(root.getChild("REFRESH_NUM_MAX").getTextTrim());
          this.mdlNum=Integer.parseInt(root.getChild("MDL_NUM_MAX").getTextTrim());
          System.out.println("this.refreshNum------"+this.refreshNum+"------this.mdlNum---"+this.mdlNum);
        }
        catch (Exception ex) {
          log.error("RunService parseXML hava a exception:" + ex.getMessage());
        }  }
      //释放对象
      public void release(Object obj)throws Exception{
        System.out.println("RunService^^^^^^^^释放^^^^^^^^^^");
        try {
          Thread thread= (ThreadRefresh)obj;
          threadPool.add(thread);
          //空闲的个数加1
          free++;
          //运行线程数 减1
          count--;
        }
        catch (Exception ex) {
          log.error(ex.getMessage());
          throw ex;
        }  }
    //从池中取一个线程
      public ThreadRefresh process() throws Exception{
        ThreadRefresh thread=null;
        System.out.println("-------process---------");
        try {
          System.out.println("free-number is--"+free);
          //如果空闲的个数为0的话
          if (free <= 0) {
            System.out.println("----- busy---"+count);
            new Thread().sleep(1000);
            this.process();
          }
          else {
            System.out.println("----- free---"+free);
            //      ThreadRefresh thread=(ThreadRefresh)
            Iterator it = threadPool.iterator();
            if (it.hasNext()) {
             thread = (ThreadRefresh)it.next();
             threadPool.remove(thread);
            }
            free--;
            count++;
          }
        }
        catch (Exception ex) {
          log.error(ex.getMessage());
          throw ex;
        }
        return thread;
      }
    }
    下面是线程类:public class ThreadRefresh extends Thread{
      //待刷新模型命令行参数
      public String param;
      public void SetParam(String param){
        this.param=param;
      }
      //updMdlExeAddress
      public String updMdlExeUrl;
      public void setUpdMdlExeUrl(String updMdlExeUrl){
        this.updMdlExeUrl=updMdlExeUrl;
      }//SimpleThread类的构造函数,它用来告诉客户端启动的是第几号进程
     public ThreadRefresh() {
     }
     public void run() {
        try {
          Runtime runTime = Runtime.getRuntime();
          System.out.println("param--------"+this.updMdlExeUrl+this.param);
          runTime.exec(this.updMdlExeUrl+this.param);      //下面测试用--代替运行。exe所用的时间测试用
         // this.sleep(10000);
         int j=0;
         for(int i=0;i<2000000001;i++){
           j=i;
         }     System.out.println("10000 以后~~~~"+j);
    //runTime.exec("D:/misc-report/广东/cubeManage/UpdateMdl "+this.param);
    //runTime.exec("D:/misc-report/广东/cubeManage/UpdateMdl "+"1(1 2)@A_test@F"+this.param);
        }catch (Exception ex) {
          System.out.println("----ThreadRefresh-----刷新异常-------");
        }
     }
    }
      

  15.   

    指点一下我的问题?是不是考虑错了?上面的错误点是无法  判断当前的模型是运行/等待状态还是结束状态,不好使。
    最大20个的话可以暂时不考虑的怎么动态加?
    exitValue()返回子进程的出口值。
    waitFor 
    等待子进程的完成。 如果已终止该子进程,此方法立即返回。 如果没有终止该子进程,进程的调用将阻塞,直到退出子进程子进程是什么概念?
      

  16.   

    Model就是传的一个参数而已,也就是你的String param既然放在 application里面,自然是一个全局变量,想怎么取就怎么取了。
      

  17.   

    既然放在 application里面,自然是一个全局变量,想怎么取就怎么取了。 
    错了,是先执行刷新。然后把模型信息放到list中,再放到application中的。
    application只是显示给用户看 刷新模型的当前运行信息。
      

  18.   

    如果你的那个exe没有UI,上边的代码已经能解决的你的问题了。如果有UI的话,我再给你发贴。regards