매개 변수로 실행할 수 있습니까?


178

그런 실행 파일이 실제로 존재하지 않는다는 것을 알고 있지만 "매개 변수를 허용하는 실행 파일"이 필요합니다.

이것은 내 앱 디자인 및 / 또는 피곤한 두뇌의 정신적 블록에 근본적인 결함을 지적 할 수 있으므로 기본적인 OO 원칙 위반 하지 않고 다음과 같은 것을 달성하는 방법에 대한 조언을 찾고 싶습니다 .

  private Runnable mOneShotTask = new Runnable(String str) {
    public void run(String str) {
       someFunc(str);
    }
  };  

위와 같은 것을 성취하는 방법에 대한 아이디어가 있습니까?


7
이제 사용할 수 있습니다 Consumer<T>.
Alex78191

1
이 질문에 대한 다양한 답변을 읽었습니다. 아무도 적절한 인터페이스를 추가하여 프로젝트에 필요한 Runnables (1, 2, 3 또는 그 이상의 인수)를 추가 할 수 있다고 말한 것은 아무도 이상하지 않은 것 같습니다. : 나는 여기에 관심이있는 사람에 대한 주석 요점 만들어 gist.github.com/jsfan3/3a66e711fd0fd233c5e4c467184adb7a
프란체스코 Galgani

이것은 "Java 스레드에 매개 변수를 전달하는 방법"과 중복되지 않습니다. 그리고 현대의 대답은 @ Alex78191과 같이 말합니다 : useConsumer<T>
Epaga

답변:


228

글을 올린 지 9 년이 지났지 만 솔직히 말해서 Java는 그 이후로 몇 가지 개선을했습니다. 나는 원래의 대답을 아래에 남겨 둘 것이지만, 사람들이 그 안에있는 것을 할 필요는 없다. 9 년 전 코드 검토 중에 왜 그들이 그것을했는지, 아마도 승인하지 않았는지 질문했을 것입니다. 현대 람다를 사용할 수 있으면 구식 접근 방식을 권장하는 투표가 많은 답변을 얻는 것은 무책임합니다. 제안 :

void foo(final String str) {
    Thread t = new Thread(() -> someFunc(str));
    t.start();
}

이전과 마찬가지로, 스레드를 의미있는 방식으로 처리하는 것과 같은 세부 사항은 독자에게 연습으로 남아 있습니다. 그러나 람다 사용을 두려워한다면 멀티 스레드 시스템을 더 두려워해야합니다.

원래 답변 :

메소드에서 클래스를 바로 선언 할 수 있습니다

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();
}

다들 감사 해요! 제안 된 모든 솔루션은 동일한 접근 방식을 가리 키지 만 하나만 허용 할 수 있습니다. 나는 이것을 스스로 생각 해낼 수 없어서 매우 피곤해야한다. 모두 +1
uTubeFan

18
실제로, 대부분의 사람들은 메소드 안에서 클래스를 선언 할 수 있다는 것을 모른다. 어떤 사람들은 스타일이 좋지 않다고 생각할 것입니다. 나는 그것이 맛의 문제라고 생각합니다. :)
corsiKa

3
공개 인터페이스 ResultRunnable <T> {공개 무효 실행 (T 결과); }
Roman M

46

함수에 넣을 수 있습니다.

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;

}

(이 매개 변수를 사용할 때 내 매개 변수는 정수 ID로 ID-> myRunnables의 해시 맵을 만드는 데 사용되었습니다. 이렇게하면 해시 맵을 사용하여 처리기에서 다른 myRunnable 객체를 게시 / 제거 할 수 있습니다.)


3
코드를 공유해 주셔서 감사합니다. 사람들이 그저 비명을 지르는 대신 그렇게하는 것을 좋아합니다. 한 가지 질문-메모리 누수와 관련하여 위의 접근법은 괜찮습니까? 전달한 모든 참조는 올바르게 처리됩니까?
nikib3ro

2
@ kape123 대답은 "그것은 달려있다"입니다. 오랫동안 한 Runnable방법으로 반환 된 객체 어디서나 존재의는 paramStr아마도 가비지 컬렉션을받을 수 없습니다. 객체가 존재하지만 다시 실행할 수없는 경우 JIT (또는 javac)가 범위에서 객체를 제거하기로 결정할 수 있지만 향후 변경 될 수 있으므로 이러한 최적화에 의존해서는 안됩니다.
corsiKa

"코드를 공유해 주셔서 감사합니다. 사람들이 그저 비명을 지르는 대신 그렇게하는 것을 좋아합니다." - 뭐?
Rob Grant

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));

객체 자체를 반환하고 매개 변수를 사용하여 초기화하는 초기화 함수를 만듭니다.


1
불행하게도 당신은 변수에 할당하고) (초기화 호출 할 수 없습니다
앤드류 Glukhoff

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;
    }
}

2
이 추상 클래스를 사용하여 매개 변수로 실행 파일을 실행하는 방법은 무엇입니까?
EZDsIt

매개 변수와 함께 생성자를 사용 하고 public RunnableArg(Object... args) { setArgs(args); } 로컬 클래스를 설명 class ActionArg extends RunnableArg { public ActionArg(Object... arg) { super(arg); } @Override public void run() { /* getArgs() and process them */ } }하고 사용합니다. Thread t = new Thread(new ActionArg( %param_object(s)% )); t.start();
GSD.Aaz

10

두 가지 옵션이 있습니다.

  1. 명명 된 클래스를 정의하십시오. 명명 된 클래스의 생성자에 매개 변수를 전달하십시오.

  2. 익명 클래스를 "매개 변수"에 가깝게하십시오. 로 표시해야합니다 final.




5

먼저 new Runnable () 또는 run ()에 전달할 인수가 필요하기 위해 여기서 달성하려는 것이 무엇인지 알고 싶습니다. 일반적인 방법은 시작하기 전에 멤버 변수를 설정하여 데이터 (str)를 스레드에 전달하는 Runnable 객체를 가져야합니다. 그런 다음 run () 메소드는 이러한 멤버 변수 값을 사용하여 someFunc ()를 실행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.