Java 스레드에 매개 변수를 전달하는 방법
내가 어떻게 매개 변수를 실로 전달할 수 있는지 누가 나에게 제안해 줄 수 있니?
또한, 익명 수업에는 어떤 효과가 있을까?
생성자의 매개 변수를 실행 가능한 개체로 전달해야 하는 경우:
public class MyRunnable implements Runnable {
public MyRunnable(Object parameter) {
// store parameter for later user
}
public void run() {
}
}
그리고 이를 다음과 같이 실행한다.
Runnable r = new MyRunnable(param_value);
new Thread(r).start();
익명 클래스의 경우:
질문 편집에 대한 응답은 익명 클래스에 대해 어떻게 작동하는지 입니다.
final X parameter = ...; // the final is important
Thread t = new Thread(new Runnable() {
p = parameter;
public void run() {
...
};
t.start();
명명된 클래스:
스레드를 확장(또는 실행 가능을 구현)하는 클래스와 전달하려는 매개 변수를 가진 생성자가 있는 경우.그런 다음 새 스레드를 만들 때 인수를 전달한 다음 스레드를 시작해야 하는데, 다음과 같은 것이 있다.
Thread t = new MyThread(args...);
t.start();
Runnable은 Thread BTW보다 훨씬 더 좋은 해결책이다.그래서 나는 다음을 선호한다.
public class MyRunnable implements Runnable {
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void run() {
}
}
Thread t = new Thread(new MyRunnable(parameter));
t.start();
이 답은 기본적으로 이와 유사한 질문과 같다.스레드 개체로 매개 변수를 전달하는 방법
실행 가능 또는 스레드 클래스의 생성자를 통해
class MyThread extends Thread {
private String to;
public MyThread(String to) {
this.to = to;
}
@Override
public void run() {
System.out.println("hello " + to);
}
}
public static void main(String[] args) {
new MyThread("world!").start();
}
이 대답은 매우 늦게 오지만, 누군가 유용하다고 여길지도 모른다.에 매개 변수를 전달하는 방법Runnable
명명된 클래스를 선언하지 않고(인라이너의 경우):
String someValue = "Just a demo, really...";
new Thread(new Runnable() {
private String myParam;
public Runnable init(String myParam) {
this.myParam = myParam;
return this;
}
@Override
public void run() {
System.out.println("This is called from another thread.");
System.out.println(this.myParam);
}
}.init(someValue)).start();
물론 당신은 실행을 연기할 수 있다.start
좀 더 편리하거나 적절한 순간에.그리고 무엇이 그 서명이 될 것인지는 당신에게 달려 있다.init
방법(그래서 더 많은 그리고/또는 다른 주장이 필요할 수도 있다) 그리고 물론 그것의 이름까지도 포함할 수 있지만, 기본적으로 당신은 아이디어를 얻는다.
사실 이니셜라이저 블록을 사용하여 익명 클래스에 매개 변수를 전달하는 다른 방법도 있다.다음을 고려하십시오.
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
private String myParam;
private int myOtherParam;
// instance initializer
{
this.myParam = someValue;
this.myOtherParam = anotherValue;
}
@Override
public void run() {
System.out.println("This comes from another thread.");
System.out.println(this.myParam + ", " + this.myOtherParam);
}
}).start();
그래서 모든 일은 이니셜라이저 블록 안에서 일어난다.
때, 은 스스튜어드 의 가 필요하다Runnable
변수를 매개 변수를 전달하는 가장 쉬운 방법은 매개 변수를 생성자에게 인수로 전달하는 것이다.
public class MyRunnable implements Runnable {
private volatile String myParam;
public MyRunnable(String myParam){
this.myParam = myParam;
...
}
public void run(){
// do something with myParam here
...
}
}
MyRunnable myRunnable = new myRunnable("Hello World");
new Thread(myRunnable).start();
그런 다음 스레드가 실행되는 동안 매개 변수를 변경하려면 실행 가능한 클래스에 세터 메서드를 추가하십시오.
public void setMyParam(String value){
this.myParam = value;
}
일단 이것을 가지고 있으면 다음과 같이 호출하여 파라미터의 값을 변경할 수 있다.
myRunnable.setMyParam("Goodbye World");
물론 파라미터가 변경되었을 때 액션을 트리거하려면 잠금장치를 사용해야 하기 때문에 사물이 상당히 복잡해진다.
몇 년 늦었다는 건 알지만 이 문제를 우연히 접하고 비정통적으로 접근했다.새로운 수업을 만들지 않고 하고 싶었기 때문에 이렇게 생각해 낸 것이다.
int x = 0;
new Thread((new Runnable() {
int x;
public void run() {
// stuff with x and whatever else you want
}
public Runnable pass(int x) {
this.x = x;
return this;
}
}).pass(x)).start();
다음 중 하나를 확장하십시오. class
또는 그 class
원하는 대로 매개 변수를 제공하십시오.문서에는 간단한 예가 있다.내가 그들을 여기에 모을게.
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeThread p = new PrimeThread(143);
p.start();
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
. . .
}
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
스레드를 생성하려면 일반적으로 Runnable 구현을 직접 생성하십시오.이 클래스의 생성자에 있는 스레드에 매개 변수를 전달하십시오.
class MyThread implements Runnable{
private int a;
private String b;
private double c;
public MyThread(int a, String b, double c){
this.a = a;
this.b = b;
this.c = c;
}
public void run(){
doSomething(a, b, c);
}
}
Runnable을 구현하는 클래스를 작성하고, 적절하게 정의된 생성자에서 필요한 모든 것을 통과시키거나, 적절한 매개 변수를 사용하여 super()를 호출하는 적절하게 정의된 생성자와 함께 스레드를 확장하는 클래스를 쓰십시오.
Java 8에서 당신은 사용할 수 있다.lambda
Concurrency API &가 포함된 표현식ExecutorService
스레드를 직접 사용하기 위한 보다 높은 수준의 대체:
newCachedThreadPool()
필요에 따라 새 스레드를 생성하지만 이전에 생성한 스레드가 있을 때 재사용하는 스레드 풀 생성.이러한 풀은 일반적으로 단명 비동기 작업을 많이 실행하는 프로그램의 성능을 향상시킬 것이다.
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
참고 항목executors
자바도크
자바 8을 기준으로 람다를 사용하여 사실상 최종적인 파라미터를 캡처할 수 있다.예를 들면 다음과 같다.
final String param1 = "First param";
final int param2 = 2;
new Thread(() -> {
// Do whatever you want here: param1 and param2 are in-scope!
System.out.println(param1);
System.out.println(param2);
}).start();
시작() 및 실행() 방법을 통과하는 매개 변수:
// Tester
public static void main(String... args) throws Exception {
ThreadType2 t = new ThreadType2(new RunnableType2(){
public void run(Object object) {
System.out.println("Parameter="+object);
}});
t.start("the parameter");
}
// New class 1 of 2
public class ThreadType2 {
final private Thread thread;
private Object objectIn = null;
ThreadType2(final RunnableType2 runnableType2) {
thread = new Thread(new Runnable() {
public void run() {
runnableType2.run(objectIn);
}});
}
public void start(final Object object) {
this.objectIn = object;
thread.start();
}
// If you want to do things like setDaemon(true);
public Thread getThread() {
return thread;
}
}
// New class 2 of 2
public interface RunnableType2 {
public void run(Object object);
}
Runnable에서 클래스를 추출할 수 있으며, 시공 중에(예:) 매개 변수를 전달하십시오.
그런 다음 Thread.start(Runnable r)를 사용하여 실행하십시오;
스레드가 실행되는 동안, 호출 스레드에서 파생된 객체에 대한 참조를 잡고 적절한 세터 메서드를 호출하십시오(해당될 경우 동기화).
변수를 런너블에 전달하는 간단한 방법이 있다.코드:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
에 매개 변수를 전달할 수 없음run()
방법서명은 다음과 같이 알려준다.아마도 이 작업을 수행하는 가장 쉬운 방법은 생성자에 있는 파라미터를 사용하여 최종 변수에 저장하는 것이다.
public class WorkingTask implements Runnable
{
private final Object toWorkWith;
public WorkingTask(Object workOnMe)
{
toWorkWith = workOnMe;
}
public void run()
{
//do work
}
}
//...
Thread t = new Thread(new WorkingTask(theData));
t.start();
일단 그렇게 하면 - 'WorkingTask'에 전달되는 개체의 데이터 무결성에 주의해야 한다.이제 데이터가 서로 다른 두 개의 스레드에 존재하므로 스레드가 안전한지 확인해야 한다.
한 가지 추가 옵션: 이 접근 방식을 통해 비동기 함수 호출과 같이 실행 가능한 항목을 사용할 수 있다.만약 여러분의 과제가 결과를 반환할 필요가 없다면, 예를 들어, 그것은 여러분이 어떻게 "발견"을 반환하는지에 대해 걱정할 필요가 없는 몇몇 행동을 할 뿐이다.
이 패턴은 당신이 어떤 내부 상태를 필요로 하는 항목을 재사용할 수 있게 해준다.매개 변수를 전달하지 않을 경우 매개 변수에 대한 프로그램 액세스를 중재하기 위해 생성자 관리에서 매개 변수를 전달해야 한다.사용 사례에 다른 발신자 등이 포함된 경우 더 많은 확인이 필요할 수 있다.
public class MyRunnable implements Runnable
{
private final Boolean PARAMETER_LOCK = false;
private X parameter;
public MyRunnable(X parameter) {
this.parameter = parameter;
}
public void setParameter( final X newParameter ){
boolean done = false;
synchronize( PARAMETER_LOCK )
{
if( null == parameter )
{
parameter = newParameter;
done = true;
}
}
if( ! done )
{
throw new RuntimeException("MyRunnable - Parameter not cleared." );
}
}
public void clearParameter(){
synchronize( PARAMETER_LOCK )
{
parameter = null;
}
}
public void run() {
X localParameter;
synchronize( PARAMETER_LOCK )
{
localParameter = parameter;
}
if( null != localParameter )
{
clearParameter(); //-- could clear now, or later, or not at all ...
doSomeStuff( localParameter );
}
}
}
스레드 t = 새 스레드(새 MyRunnable(매개 변수)), t.start();
처리 결과가 필요한 경우 하위 태스크가 완료될 때 MyRunnable의 완료도 조정해야 한다.전화를 돌려주거나 'T'등에서 그냥 기다릴 수도 있다.
특별히 Android용
콜백(callback)을 위해 나는 보통 나만의 일반을 구현한다.Runnable
입력 매개 변수 포함:
public interface Runnable<TResult> {
void run(TResult result);
}
사용법은 간단하다.
myManager.doCallbackOperation(new Runnable<MyResult>() {
@Override
public void run(MyResult result) {
// do something with the result
}
});
관리자:
public void doCallbackOperation(Runnable<MyResult> runnable) {
new AsyncTask<Void, Void, MyResult>() {
@Override
protected MyResult doInBackground(Void... params) {
// do background operation
return new MyResult(); // return resulting object
}
@Override
protected void onPostExecute(MyResult result) {
// execute runnable passing the result when operation has finished
runnable.run(result);
}
}.execute();
}
클래스에 다음 로컬 변수 만들기extends Thread
또는implements Runnable
.
public class Extractor extends Thread {
public String webpage = "";
public Extractor(String w){
webpage = w;
}
public void setWebpage(String l){
webpage = l;
}
@Override
public void run() {// l is link
System.out.println(webpage);
}
public String toString(){
return "Page: "+webpage;
}}
이렇게 하면 변수를 실행할 때 전달할 수 있다.
Extractor e = new Extractor("www.google.com");
e.start();
출력:
"www.google.com"
먼저 나는 다른 답변들이 사실이라는 것을 지적하고 싶다.그러나, 생성자의 매개변수를 사용하는 것이 여러분 모두에게 가장 좋은 아이디어는 아닐 수 있다.
많은 시나리오에서 당신은 "익명 이너 클래스"를 사용하기를 원할 것이고, 그리고 오버라이드 할 것이다.run()
방법, 모든 사용에 대한 특정 클래스를 정의하는 것은 고통스럽기 때문이다.(new MyRunnable(){...}
)
Runnable을 생성할 때 생성자에서 매개 변수를 전달하지 못할 수 있음예를 들어, 이 개체를 하나의 메서드에 전달하면 별도의 스레드에서 작업을 수행한 다음 실행 가능을 호출하여 해당 작업의 결과를 해당 메서드에 적용하십시오.
이 경우 다음과 같은 방법을 사용하여 다음을 수행하십시오.public MyRunnable withParameter(Object parameter)
는 훨씬 더 유용한 선택으로 판명될지도 모른다.
나는 이것이 그 문제에 대한 최선의 해결책이라고 주장하지는 않지만, 그것은 그 일을 끝낼 것이다.
참조URL: https://stackoverflow.com/questions/877096/how-can-i-pass-a-parameter-to-a-java-thread
'IT이야기' 카테고리의 다른 글
자바에서 스트림 정말 디버깅만 peek은? (0) | 2022.05.17 |
---|---|
Nuxt:js 파일에서vuex 상점에 액세스 할 수 없다. (0) | 2022.05.17 |
코틀린에서 자바 정전기법에 해당하는 것은 무엇인가? (0) | 2022.05.16 |
Vuex, 루트 게이터에서 이름보다 앞선 모듈 게이터를 사용할 수 없는가? (0) | 2022.05.16 |
뮤텍스를 고정하는 나사산을 결정할 수 있는가? (0) | 2022.05.16 |