Potrzebuję „Runnable, który akceptuje parametr”, chociaż wiem, że taki runnable tak naprawdę nie istnieje.
Może to wskazywać na fundamentalną wadę w projekcie mojej aplikacji i / lub blokadę umysłową w moim zmęczonym mózgu, więc mam nadzieję, że znajdę tutaj kilka porad, jak osiągnąć coś takiego, jak poniżej, bez naruszania podstawowych zasad OO:
private Runnable mOneShotTask = new Runnable(String str) {
public void run(String str) {
someFunc(str);
}
};
Masz pomysł, jak osiągnąć coś podobnego do powyższego?
Consumer<T>
.Consumer<T>
Odpowiedzi:
Cóż, minęło prawie 9 lat, odkąd pierwotnie to opublikowałem i szczerze mówiąc, od tego czasu Java wprowadziła kilka ulepszeń. Zostawię moją pierwotną odpowiedź poniżej, ale ludzie nie muszą robić tego, co w niej jest. 9 lat temu, podczas przeglądu kodu, zapytałbym, dlaczego to zrobili i może to zaakceptowali, a może nie. Przy dostępnych nowoczesnych lambdach nieodpowiedzialne jest posiadanie tak wysoko ocenianej odpowiedzi zalecającej przestarzałe podejście (które, szczerze mówiąc, było wątpliwe na początku ...) We współczesnej Javie ten przegląd kodu zostałby natychmiast odrzucony, a to byłoby zasugerował:
Tak jak poprzednio, szczegóły, takie jak obsługa tego wątku w znaczący sposób, pozostawia się czytelnikowi jako ćwiczenie. Ale mówiąc wprost, jeśli boisz się używania lambd, jeszcze bardziej powinieneś bać się systemów wielowątkowych.
Oryginalna odpowiedź, tylko dlatego, że:
Możesz zadeklarować klasę bezpośrednio w metodzie
źródło
Możesz umieścić to w funkcji.
(Kiedy tego użyłem, moim parametrem był identyfikator całkowity, którego użyłem do utworzenia skrótu ID -> myRunnables. W ten sposób mogę użyć hashmap do opublikowania / usunięcia różnych obiektów myRunnable w module obsługi.)
źródło
Runnable
obiekt zwrócony przez metodę istnieje gdziekolwiek,paramStr
prawdopodobnie nie będzie on kwalifikował się do czyszczenia pamięci. Jest możliwe, że jeśli obiekt istnieje, ale nie można go już nigdy uruchomić, JIT (lub nawet javac) może zdecydować o usunięciu go z zakresu, ale nie powinniśmy polegać na takich optymalizacjach, ponieważ mogą się one zmienić w przyszłości.Utwórz funkcję init, która zwraca sam obiekt i inicjalizuje z nim parametry.
źródło
Używam następującej klasy, która implementuje interfejs Runnable . Dzięki tej klasie możesz łatwo tworzyć nowe wątki z argumentami
źródło
public RunnableArg(Object... args) { setArgs(args); }
następnie opisać lokalną klasę:class ActionArg extends RunnableArg { public ActionArg(Object... arg) { super(arg); } @Override public void run() { /* getArgs() and process them */ } }
i użyć jejThread t = new Thread(new ActionArg( %param_object(s)% )); t.start();
Masz dwie możliwości:
Zdefiniuj nazwaną klasę. Przekaż parametr do konstruktora nazwanej klasy.
Zamknij klasę anonimową nad "parametrem". Pamiętaj, aby oznaczyć go jako
final
.źródło
Od wersji Java 8 najlepszą odpowiedzią jest użycie
Consumer<T>
:https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html
Jest to jeden z funkcjonalnych interfejsów, co oznacza, że można go nazwać wyrażeniem lambda:
źródło
Najpierw chciałbym wiedzieć, co próbujesz tutaj osiągnąć, aby potrzebować argumentu do przekazania do new Runnable () lub do run (). Zwykłym sposobem powinno być posiadanie obiektu Runnable, który przekazuje dane (str) do swoich wątków przez ustawienie zmiennych składowych przed rozpoczęciem. Następnie metoda run () używa tych wartości zmiennych składowych do wykonania funkcji someFunc ()
źródło