帮助在Java中实现Runnable

帮助在Java中实现Runnable,java,multithreading,runnable,Java,Multithreading,Runnable,我正在和我的团队一起做一个java项目。总之,我们有一个主类,它有一个实例化和调用“Save”类的方法。这个“Save”类使用几个构造函数和一些可见和不可见的方法将文件保存回服务器。该类是CPU密集型且耗时的,这会阻止主应用程序显示进度条对话框窗口,让用户知道保存的状态。他们要求我修改“Save”类,使其能够从自己的线程中派生出来,以便主应用程序的其余部分可以完成向用户显示信息的较小任务 以下是it的一般概念: 我目前是Java线程的新手,但我对它们的工作原理有基本的了解。据我所知,一个实现

我正在和我的团队一起做一个java项目。总之,我们有一个主类,它有一个实例化和调用“Save”类的方法。这个“Save”类使用几个构造函数和一些可见和不可见的方法将文件保存回服务器。该类是CPU密集型且耗时的,这会阻止主应用程序显示进度条对话框窗口,让用户知道保存的状态。他们要求我修改“Save”类,使其能够从自己的线程中派生出来,以便主应用程序的其余部分可以完成向用户显示信息的较小任务

以下是it的一般概念:

我目前是Java线程的新手,但我对它们的工作原理有基本的了解。据我所知,一个实现Runnable的类,当它被实例化为一个新线程时,run()方法被执行。问题是,对于不同类型的文件,不同类型的保存有不同的方法,因此如何将这些方法实现到run()方法中?在新线程中实例化类并对其调用.start()时,run()方法是唯一执行的方法吗

解决这个问题的好办法是什么?“Save”类是否需要重新设计以使其实现可运行

如果需要更多的细节,请告诉我。谢谢你的洞察力


更新:谢谢大家的帮助!这些解决方案将在未来派上用场。

最简单的方法是使每个解决方案都可以运行。将参数设置为实例字段,而不是传递到run中

class SaveThatCommand implements Runnable {
     private final StatusWindow s;
     //constructor that initializes s
     public void run() {
        //save that code
        s.update();
     }
}
根据您的需求,实现这一点的一个更简单的方法是创建一个匿名的内部类

public void doSave(final StatusWindow s) {
    if (saveThis) {
        Thread t = new Thread( new Runnable() {
            public void run() {
               saveThis(s);
            }
        });
        t.start();
    }
    //...
}

您有点不正确:run方法在传递给线程的构造函数时执行,然后在该线程上调用start()。

最简单的方法是为每个线程创建一个runnable。将参数设置为实例字段,而不是传递到run中

class SaveThatCommand implements Runnable {
     private final StatusWindow s;
     //constructor that initializes s
     public void run() {
        //save that code
        s.update();
     }
}
根据您的需求,实现这一点的一个更简单的方法是创建一个匿名的内部类

public void doSave(final StatusWindow s) {
    if (saveThis) {
        Thread t = new Thread( new Runnable() {
            public void run() {
               saveThis(s);
            }
        });
        t.start();
    }
    //...
}

您有点不正确:run方法是在传递给线程的构造函数时执行的,然后在该线程上调用start()

a) 可以将带有if块的代码移动到run()方法中

b) 每个文档类型可以有一个实现runnable的类


方法a)更简单,因为它需要对现有代码进行更少的更改。但是方法b)是面向对象的方法:“每个任务一个类”。

有两种方法:

a) 可以将带有if块的代码移动到run()方法中

b) 每个文档类型可以有一个实现runnable的类


方法a)更简单,因为它需要对现有代码进行更少的更改。但是方法b)是一种面向对象的方法:“每个任务一个类”。

一个完整的解决方案是扩展
可运行的
类,并将所需的参数和所需的保存类型传递给构造函数。然后,您可以使用以下工具运行它们:

new Thread(saveRunnable).start(); 新线程(saveRunnable).start(); 一个更简单的解决方案是在save类中实现如下模式:

public void saveThis(StatusWindow s) { Runnable r = new Runnable() { private StatusWindow s; public Runnable setStatusWindow(StatusWindow s) { this.s = s; return this; } @Override public void run() { this.Save.saveThisInternal(this.s); } }.setStatusWindow(s); new Thread(r).start(); } public void saveThisInternal(StatusWindow s) { //alot of code s.update(); } 公共作废保存此(状态窗口){ Runnable r=新的Runnable(){ 私有状态; 公共可运行setStatusWindow(状态窗口){ 这个.s=s; 归还这个; } @凌驾 公开募捐{ this.Save.saveThisInternal(this.s); } }.设置状态窗口; 新线程(r.start(); } 公共作废保存此内部(状态窗口){ //大量代码 s、 更新(); }
完整的解决方案是扩展
Runnable
类,并将所需的参数和所需的保存类型传递给构造函数。然后,您可以使用以下工具运行它们:

new Thread(saveRunnable).start(); 新线程(saveRunnable).start(); 一个更简单的解决方案是在save类中实现如下模式:

public void saveThis(StatusWindow s) { Runnable r = new Runnable() { private StatusWindow s; public Runnable setStatusWindow(StatusWindow s) { this.s = s; return this; } @Override public void run() { this.Save.saveThisInternal(this.s); } }.setStatusWindow(s); new Thread(r).start(); } public void saveThisInternal(StatusWindow s) { //alot of code s.update(); } 公共作废保存此(状态窗口){ Runnable r=新的Runnable(){ 私有状态; 公共可运行setStatusWindow(状态窗口){ 这个.s=s; 归还这个; } @凌驾 公开募捐{ this.Save.saveThisInternal(this.s); } }.设置状态窗口; 新线程(r.start(); } 公共作废保存此内部(状态窗口){ //大量代码 s、 更新(); }
您的同事可能从主应用程序中的多个位置调用Save,并且希望避免必须更改所有其他代码以支持将Save作为并行操作进行保存。另外,一般来说,大多数人不喜欢自己制作线程,而是更喜欢使用ExecutorService。因此,这里介绍了如何仅通过修改Save类和使用执行器来实现这一点:

class Save{
   private static final ExecutorService executor = Executors.newCachedThreadPoolExecutor();
   //or fixed, or whatever you want. Maybe single thread executor is best if the Save code is not well suited to concurrency.

   static {
       Runtime.getRuntime().addShutdownHook(
           new Thread() {
               public void run() {
                   executor.shutdown();
               }
           }
       );
   }

   public void saveThis(StatusWindow s)
   {
      executor.execute(new SaveThis(s));
   }
   public void saveThat(StatusWindow s)
   {
      executor.execute(new SaveThat(s));
   }
   ... // some non-visible methods, even more code

   private class SaveThis implements Runnable {
       //StatusWindow member variable and constructor
       public void run() {
           //alot of code
           s.update;
       }
   }

   private class SaveThat implements Runnable {
       //StatusWindow member variable and constructor
       public void run() {
           //alot of code
           s.update;
       }
   }
 }

您的同事可能从主应用程序中的多个位置调用Save,并且希望避免必须更改所有其他代码以支持将Save作为并行操作进行保存。另外,一般来说,大多数人不喜欢自己制作线程,而是更喜欢使用ExecutorService。因此,这里介绍了如何仅通过修改Save类和使用执行器来实现这一点:

class Save{
   private static final ExecutorService executor = Executors.newCachedThreadPoolExecutor();
   //or fixed, or whatever you want. Maybe single thread executor is best if the Save code is not well suited to concurrency.

   static {
       Runtime.getRuntime().addShutdownHook(
           new Thread() {
               public void run() {
                   executor.shutdown();
               }
           }
       );
   }

   public void saveThis(StatusWindow s)
   {
      executor.execute(new SaveThis(s));
   }
   public void saveThat(StatusWindow s)
   {
      executor.execute(new SaveThat(s));
   }
   ... // some non-visible methods, even more code

   private class SaveThis implements Runnable {
       //StatusWindow member variable and constructor
       public void run() {
           //alot of code
           s.update;
       }
   }

   private class SaveThat implements Runnable {
       //StatusWindow member variable and constructor
       public void run() {
           //alot of code
           s.update;
       }
   }
 }

是的,我完全忘记在那里添加.start(),我将编辑我的问题。Thanx:)我喜欢第二个建议,现在它似乎很快也很容易实现。是的,我完全忘了在那里添加。start(),我将编辑我的问题。Thanx:)我喜欢第二个建议,现在看来它很快就可以实现了