【问题标题】:Executing methods one after another and one at a time一个接一个地执行方法
【发布时间】:2016-07-04 07:03:39
【问题描述】:

我想在一个按钮内执行许多方法,但有些需要更少的时间,有些需要更多的时间来处理,我希望它们以特定的顺序运行它们,因为一种方法适用于另一种方法的输出。我的按钮执行如下:-

{
Basic b = new Basic();
b.method1(); //Normal processing
b.method2(); //Normal processing
b.method3(); //Heavy  processing takes a lot of time like 5 to 10sec
b.method4(); //Basic  processing
b.method5(); //Medium Processing FileHandling(works on 5 file)
}

所以发生的事情是一切都很完美,除了方法2的执行之外,但是随着方法3的出现,它变得一团糟。所以我的事情是我的方法3被跳过并且方法4和方法5被执行结束了给我一个空指针异常,因为它们取决于从 method3 的执行中收到的数据。

有人能告诉我如何确保我的方法 4 和 5 仅在我的方法 3 完成后运行,并且仅供参考,我的方法 3 包含来自不同类的 2 个方法,一个是制作一些脚本,另一个是执行它,这需要真正的自从它使用 bash shell 以来的时间。

P.S.-当我的按钮执行完成时,我看到我的方法 3 没有做任何事情,比如它已经被跳过或其他事情。

代码:-

public void method3(String abstarpath,String filename,String parapth)
{
    try{
    String cmd1 = "tar xzf "+abstarpath;
    String cmd2 = "mv "+ parapth+"/"+filename +" /home/apoorv/Desktop/";
    txtarea.append("#"+cmd1+"\n");
    txtarea.append("#"+cmd2+"\n");
    executeCommands(cmd1, cmd2);            
    }catch(Exception e){
        txtarea.append("#"+e+"\n");
        e.printStackTrace();
    }
    txtarea.append("\n");
}

public void executeCommands(String cmd1,String cmd2) throws IOException {

    File tempScript = createTempScript(cmd1,cmd2);

    try {
        ProcessBuilder pb = new ProcessBuilder("bash", tempScript.toString());
        pb.inheritIO();
        Process process = pb.start();
        process.waitFor();
    } catch (InterruptedException e) {
        txtarea.append("#"+e+"\n");
        e.printStackTrace();
    } finally {
        tempScript.delete();
    }
}

public File createTempScript(String cmd1,String cmd2) throws IOException {
    File tempScript = File.createTempFile("script", null);

    Writer streamWriter = new OutputStreamWriter(new FileOutputStream(
            tempScript));
    PrintWriter printWriter = new PrintWriter(streamWriter);

    printWriter.println("#!/bin/bash");
    printWriter.println(cmd1);
    printWriter.println(cmd2);
    printWriter.close();

    return tempScript;
}

【问题讨论】:

  • 如果您的观察是正确的,那么在 method3 代码中一定存在一些并发性。检查线程创建或那个方向的东西。然后看看你是否可以等待它完成。
  • @Ap00rv 不,我们不能。您需要在 method3 中显示更多代码。如何处理这在很大程度上取决于你在那里做什么。
  • 顺便说一句:如果涉及繁重的处理,则不应在 EDT 上执行任何此操作。制作一个在后台线程上完成所有操作的异步方法。为避免在此期间再次点击该按钮,您可以在任务运行时禁用它。见:docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
  • 所示代码 sn-p 以 顺序 方式调用所有方法 - 一个接一个。除非这些方法不涉及线程,否则代码将按预期工作。但是,如果涉及到一些线程,则代码的某些部分可以同时运行。这在很大程度上取决于这些方法中的代码。所以展示他们的代码(或者可能是他们代码的重要部分)。否则,我们无法为您提供帮助。
  • 嗯,waitFor 应该阻塞直到进程完成...我没有看到明显的错误。

标签: java multithreading user-interface


【解决方案1】:

查看您的代码,您遇到的问题似乎与并发无关。问题是您的 main 方法不知道 methodX() 方法是否成功完成。

您可以做的是将异常处理移至您的主要方法:

try {
    Basic b = new Basic();    
    b.method1(); //Normal processing
    b.method2(); //Normal processing
    b.method3(); //Heavy  processing takes a lot of time like 5 to 10sec
    b.method4(); //Basic  processing
    b.method5(); //Medium Processing FileHandling(works on 5 file)
}
catch (Exception e) {
    // error handling
}

(当然,您必须从其他方法中删除异常处理)。

然后,只要其中一个方法抛出异常,就会跳过其余方法并执行异常处理程序。

【讨论】:

    【解决方案2】:

    这对你有帮助

    static void Main(string[] args)
        {
    
            SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
    
            Task.Factory.StartNew(() =>
            {
                return Method1();
            }).ContinueWith((t) => {
                return Method2(t.Result.ToString());
    
            }).ContinueWith((p) =>
            {
                return Method3(p.Result.ToString());
            }, TaskScheduler.FromCurrentSynchronizationContext());
    
            Console.ReadLine();           
        }
    
        public static string Method1()
        {
            for(int i =0;i<20;i++)
            {
                Thread.Sleep(400);
                Console.WriteLine("Working in Method1");
            }
            return "return from method1";
    
        }
        public static string Method2(string input)
        {
            for (int i = 0; i < 30; i++)
            {
                Thread.Sleep(600);
                Console.WriteLine(input + " to Method 2");
            }
            return "Input from Method2";
        }
        public static string Method3(string input)
        {
            for (int i = 0; i < 50; i++)
            {
                Thread.Sleep(300);
                Console.WriteLine(input + " to Method 3");
            }
            return "Input from Method3";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 2012-05-10
      • 2020-09-06
      相关资源
      最近更新 更多