【问题标题】:How to call Java concurrent threads in web application如何在 Web 应用程序中调用 Java 并发线程
【发布时间】:2015-12-01 11:33:41
【问题描述】:

我正在开发一些 Web 应用程序,但我遇到了一些问题,我需要您的帮助。 我使用 struts 框架开发了一个 java web 应用程序。此应用程序从用户那里获取源文件夹并复制到服务器内的唯一目录中,它将对每个源文件夹执行批处理,批处理将在相应文件夹内写入日志。 上传和复制源文件夹工作正常,但面临的真正问题是同时执行批处理。 当一个用户上传源文件夹并开始批处理执行,同时另一个用户也上传源文件夹并开始批处理时,我需要知道第一个用户批处理完成和第二个用户完成的时间。如何跟踪并发线程是否完成。我正在使用 Executor executor = Executors.newCachedThreadPool();请在下面找到代码

 private class BackgroundTask extends SwingWorker<Integer, String> {
        String srcpath;
 String log;
         BackgroundTask(String path)
         {
             this.srcpath=path;
         }
            private int status;

            public BackgroundTask() {

            }
            @Override
            protected Integer doInBackground() {
                try {
                    final File batchFile = new File("D://chetan//bin//runner.bat");
                 ProcessBuilder builder = new ProcessBuilder();
                  builder.directory(new File(srcpath));
                  String[] cmd = { "cmd", "/c",batchFile.getAbsolutePath(),"-X"};

                  for (int x = 0; x < cmd.length; x++) {
                        System.out.println("Command :" + cmd[x]);   

                    }
                     builder.command(cmd);

                     Process process;
                     process = builder.start();
                     InputStream is1 = process.getInputStream();
                        InputStreamReader isr = new InputStreamReader(is1);
                        BufferedReader br = new BufferedReader(isr);
                        String line;
                     File logfile;
                     File logpath=new File(srcpath+File.separator+"LOG");
                     if(logpath.isDirectory())
                     {
                          logfile=new File(logpath+File.separator+"runner.log");

                     }
                     else
                     {
                         logpath.mkdir();
                         logfile=new File(logpath+File.separator+"runner.log");
                     }
                     logfile.createNewFile();
                     while ((line = br.readLine()) != null) {                           
                            //appendText(line);                     
                         log+=line+"\n";                    
                     }
                     FileUtils.writeStringToFile(logfile,log);           

                    process.getInputStream().close();
                    process.getOutputStream().close();
                    process.getErrorStream().close();
                    process.destroy();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return status;
            }
            @Override
            protected void process(java.util.List<String> messages) {
               // statusLabel.setText((this.getState()).toString());               
            }

            @Override
            protected void done() {

            }

        }

二等

public class RunnerAnalysisAction extends ActionSupport implements SessionAware {
 private BackgroundTask backgroundTask;

 public String execute() {
  String projectRoot="D:\\Sample_DemoProjects\\DEMO_375530\\";
 backgroundTask = new BackgroundTask(projectRoot+ProjectName);
 Executor executor= Executors.newCachedThreadPool();
 executor.execute(backgroundTask);
return SUCCESS;  
 }
}

上面的代码工作正常,并在相应的源文件夹中创建日志文件,但我需要 知道批处理何时完成任务,因为一旦批处理完成其任务,此应用程序将触发电子邮件 给有日志的用户。如何知道特定任务完成与否。请提供一些示例代码。谢谢。

【问题讨论】:

  • 检查 CountDownLatch 在这种情况下是否对您有帮助。 javarevisited.blogspot.in/2012/07/…
  • 我不完全确定 SwingWorker 是否适合后端应用程序...?
  • 即使我尝试了 callable 并且面临的主要问题是跟踪线程如何完成。如果有任何简单的方法可以让线程完成其任务,请提出建议。

标签: java multithreading threadpool execution java.util.concurrent


【解决方案1】:

您没有指定 Web 应用程序的性质。如果它不是集群的(运行单个实例),则保留一个静态变量(或 ActionServlet 内的实例变量,即 singleton)。当来自前一个用户的线程(工作任务)已经在运行时,将此变量设置为“true”,并在线程完成时重置为 false。使用此标志检查另一个线程(来自另一个用户)是否可以运行 - true 表示无法运行,false 表示可以运行。或者将 ExecutorService 定义为共享(静态)实例,然后将其设为 SingleThreaded 池并将工作线程提交给它。希望你明白了。

【讨论】:

    【解决方案2】:

    为了跟踪并发线程,我使用了java.util.concurrent.Future。 Future 表示异步计算的结果。提供了检查计算是否完成、等待其完成以及检索计算结果的方法。只能在计算完成后使用 get 方法检索结果,必要时阻塞,直到它准备好。

    你可以试试这个完整的example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      相关资源
      最近更新 更多