用参数运行吗?

uTu*_*Fan 163 java runnable

我需要一个"Runnable接受一个参数",虽然我知道这样的runnable并不存在.

这可能指出我的应用程序设计中的根本缺陷和/或疲惫的大脑中的心理障碍,所以我希望在这里找到关于如何完成以下内容的一些建议,而不违反基本的OO原则:

  private Runnable mOneShotTask = new Runnable(String str) {
    public void run(String str) {
       someFunc(str);
    }
  };  
Run Code Online (Sandbox Code Playgroud)

知道如何完成上述内容吗?

cor*_*iKa 216

您可以在方法中声明一个类

void Foo(String str) {
    class OneShotTask implements Runnable {
        String str;
        OneShotTask(String s) { str = s; }
        public void run() {
            someFunc(str);
        }
    }
    Thread t = new Thread(new OneShotTask(str));
    t.start();
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,大多数人都不知道你可以在方法中声明一个类.有人会认为它风格很差.我想这是一个品味问题.:) (14认同)
  • 公共接口 ResultRunnable<T> { public void run(T result); } (3认同)

Hao*_* Li 43

你可以把它放在一个函数中.

String paramStr = "a parameter";
Runnable myRunnable = createRunnable(paramStr);

private Runnable createRunnable(final String paramStr){

    Runnable aRunnable = new Runnable(){
        public void run(){
            someFunc(paramStr);
        }
    };

    return aRunnable;

}
Run Code Online (Sandbox Code Playgroud)

(当我使用它时,我的参数是一个整数ID,我用它来制作ID - > myRunnables的散列图.这样,我可以使用hashmap在处理程序中发布/删除不同的myRunnable对象.)

  • 感谢您分享代码 - 我喜欢当人们这样做而不仅仅是喋喋不休.一个问题 - 在内存泄漏方面,上述方法是否正常?您通过的所有参考文件都将被妥善处理? (3认同)
  • @ kape123答案是“取决于”。只要方法返回的“ Runnable”对象在任何地方都存在,“ paramStr”可能就不符合垃圾回收的条件。如果对象存在但可能永远无法再次运行,则JIT(甚至javac)可能会决定将其从范围中删除,但是我们不应该依赖于此类优化,因为它们将来可能会发生变化。 (2认同)

小智 30

theView.post(new Runnable() {
    String str;
    @Override                            
    public void run() {
        par.Log(str);                              
    }
    public Runnable init(String pstr) {
        this.str=pstr;
        return(this);
    }
}.init(str));
Run Code Online (Sandbox Code Playgroud)

创建init函数,返回对象本身并使用它初始化参数.

  • 不幸的是,您将无法将其分配给变量并调用 init() (3认同)

ubi*_*con 11

我使用以下类来实现Runnable接口.使用此类,您可以轻松地使用参数创建新线程

public abstract class RunnableArg implements Runnable {

    Object[] m_args;

    public RunnableArg() {
    }

    public void run(Object... args) {
        setArgs(args);
        run();
    }

    public void setArgs(Object... args) {
        m_args = args;
    }

    public int getArgCount() {
        return m_args == null ? 0 : m_args.length;
    }

    public Object[] getArgs() {
        return m_args;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你如何使用这个抽象类来运行带参数的runnable? (2认同)

rli*_*bby 10

您有两种选择:

  1. 定义命名类.将您的参数传递给指定类的构造函数.

  2. 让您的匿名课程关闭您的"参数".一定要将其标记为final.


Epa*_*aga 10

从 Java 8 开始,最好的答案是使用Consumer<T>

https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html

它是函数式接口之一,这意味着您可以将其称为 lambda 表达式:

void doSomething(Consumer<String> something) {
    something.accept("hello!");
}

...

doSomething( (something) -> System.out.println(something) )

...
Run Code Online (Sandbox Code Playgroud)


atl*_*tis 5

我首先想知道你在这里要完成什么,需要将一个参数传递给新的Runnable()或run().通常的方法应该是有一个Runnable对象,它通过在启动之前设置成员变量将数据(str)传递给它的线程.然后run()方法使用这些成员变量值来执行someFunc()