Jak mogę przekazać parametr do wątku Java?
Czy ktoś może mi zasugerować Jak mogę przekazać parametr do wątku?
Również, jak to działa dla anonimowych klas?
17 answers
Musisz przekazać parametr w konstruktorze do obiektu Runnable:
public class MyRunnable implements Runnable {
public MyRunnable(Object parameter) {
// store parameter for later user
}
public void run() {
}
}
I wywołaj go w ten sposób:
Runnable r = new MyRunnable(param_value);
new Thread(r).start();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-15 16:05:16
Dla klas anonimowych:
W odpowiedzi na pytania edycje oto jak to działa dla anonimowych klas
final X parameter = ...; // the final is important
Thread t = new Thread(new Runnable() {
p = parameter;
public void run() {
...
};
t.start();
Nazwane klasy:
Masz klasę, która rozszerza wątek (lub implementuje Runnable) i konstruktor z parametrami, które chcesz przekazać. Następnie, gdy tworzysz nowy wątek, musisz podać argumenty, a następnie rozpocząć wątek, coś w tym stylu:
Thread t = new MyThread(args...);
t.start();
Runnable jest o wiele lepszym rozwiązaniem niż Thread BTW. Więc ... preferuję:
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();
Ta odpowiedź jest zasadniczo taka sama jak to podobne pytanie: Jak przekazać parametry do obiektu wątku
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:33
Poprzez konstruktor klasy Runnable lub Thread
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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 10:47:25
Kiedy tworzysz wątek, potrzebujesz instancji Runnable
. Najprostszym sposobem przekazania parametru jest przekazanie go jako argumentu konstruktorowi:
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();
Jeśli chcesz zmienić parametr podczas działania wątku, możesz po prostu dodać metodę setter do swojej klasy runnable:
public void setMyParam(String value){
this.myParam = value;
}
Gdy już to masz, możesz zmienić wartość parametru, wywołując w ten sposób:
myRunnable.setMyParam("Goodbye World");
Oczywiście, jeśli chcesz wywołać akcję, gdy parametr jest zmieniony, trzeba będzie użyć zamków, co sprawia, że rzeczy znacznie bardziej skomplikowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 10:51:16
Ta odpowiedź przychodzi bardzo późno, ale może komuś się przyda. Chodzi o to, jak przekazać parametr(y) do Runnable
bez deklarowania nazwanej klasy (przydatne dla inlinerów):
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();
Oczywiście możesz odłożyć wykonanie start
na jakiś wygodniejszy lub odpowiedni moment. I to od Ciebie zależy, jaka będzie sygnatura metody init
(więc może to wymagać więcej i / lub różnych argumentów) i oczywiście nawet jej nazwa, ale w zasadzie masz pomysł.
W rzeczywistości istnieje również inny sposób przekazywania parametru do anonimowej klasy, przy użyciu bloków inicjalizatora. Rozważ to:
String someValue = "Another demo, no serious thing...";
int anotherValue = 42;
new Thread(new Runnable() {
private String myParam;
private int myOtherParam;
{
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();
Więc wszystko dzieje się wewnątrz bloku inicjalizatora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 13:04:02
Aby utworzyć wątek, Zwykle tworzysz własną implementację Runnable. Przekazuje parametry do wątku w konstruktorze tej klasy.
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 07:15:30
Możesz albo rozszerzyć Thread
class
lub Runnable
class
i podaj parametry, jak chcesz. Istnieją proste przykłady w docs . Umieszczę je tutaj:
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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 10:46:38
Albo napisz klasę, która implementuje Runnable i przekaż wszystko, czego potrzebujesz w odpowiednio zdefiniowanym konstruktorze, albo napisz klasę, która rozszerza wątek o odpowiednio zdefiniowany konstruktor, który wywołuje super () z odpowiednimi parametrami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 10:41:02
Począwszy od Javy 8, można używać lambda do przechwytywania parametrów, które są efektywnie ostateczne . Na przykład:
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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:08
Możesz wyprowadzić klasę z Runnable i podczas budowy (powiedzmy) przekazać parametr.
Następnie uruchom go za pomocą wątku.start(Runnable r);
Jeśli masz na myśli podczas gdy wątek jest uruchomiony, po prostu przytrzymaj odniesienie do swojego pochodnego obiektu w wątku wywołującym i wywołaj odpowiednie metody settera (synchronizujące w stosownych przypadkach)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-18 10:41:41
Parametr przechodzący przez metody start() I run ():
// 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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-11 21:01:52
Istnieje prosty sposób przekazywania parametrów do runnables. Kod:
public void Function(final type variable) {
Runnable runnable = new Runnable() {
public void run() {
//Code adding here...
}
};
new Thread(runnable).start();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 03:18:22
W Javie 8 można używać wyrażeń lambda
z API współbieżności i ExecutorService
jako zamiennika wyższego poziomu do pracy bezpośrednio z wątkami:
newCachedThreadPool()
tworzy pulę wątków, która tworzy nowe wątki w razie potrzeby, ale wykorzysta wcześniej skonstruowane wątki, gdy są dostępny. Pule te zazwyczaj poprawiają wydajność programów, które wykonują wiele krótkotrwałych zadań asynchronicznych.
private static final ExecutorService executor = Executors.newCachedThreadPool();
executor.submit(() -> {
myFunction(myParam1, myParam2);
});
Zobacz executors
javadocs .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-29 09:53:51
Jeszcze jedna opcja; takie podejście pozwala na użycie elementu Runnable jak asynchroniczne wywołanie funkcji. Jeśli Twoje zadanie nie musi zwracać wyniku, np. po prostu wykonuje jakąś akcję, nie musisz się martwić o to, jak przekazujesz z powrotem "wynik".
Ten wzorzec pozwala na ponowne użycie elementu, gdzie potrzebny jest jakiś wewnętrzny stan. Gdy nie przekazujemy parametrów w konstruktorze, potrzebna jest opieka nad mediacją dostępu programów do parametrów. Możesz potrzebować więcej kontroli, jeśli twój przypadek użycia dotyczy różnych rozmówców, itp.
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 );
}
}
}
Thread t = new Thread (new MyRunnable (parametr)); t. start ();
Jeśli potrzebujesz wyniku przetwarzania, musisz również koordynować zakończenie MyRunnable po zakończeniu zadania podrzędnego. Można przekazać połączenie z powrotem lub po prostu czekać na wątku "t", itp.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 22:19:56
Specjalnie dla Androida
W celach wywołania zwrotnego zazwyczaj implementuję swój własny ogólny Runnable
z parametrami wejściowymi:
public interface Runnable<TResult> {
void run(TResult result);
}
Użycie jest proste:
myManager.doCallbackOperation(new Runnable<MyResult>() {
@Override
public void run(MyResult result) {
// do something with the result
}
});
W Menedżerze:
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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-08 11:52:46
Nie Nie można przekazać parametrów do metody run()
. Podpis mówi, że (nie ma parametrów). Prawdopodobnie najprostszym sposobem na to jest użycie specjalnie zbudowanego obiektu, który pobiera parametr w konstruktorze i przechowuje go w końcowej zmiennej:
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();
Gdy to zrobisz - musisz uważać na integralność danych obiektu, który PRZEKAZUJESZ do "WorkingTask". Dane będą teraz istnieć w dwóch różnych wątkach, więc musisz upewnić się, że jest Bezpieczny wątek.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-13 12:00:01
Utwórz zmienną lokalną w swojej klasie, która extends Thread
lub 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;
}}
W ten sposób możesz przekazać zmienną podczas jej uruchamiania.
Extractor e = new Extractor("www.google.com");
e.start();
Wyjście:
"www.google.com"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-19 13:22:32