Wątki Java
Wątki Java
Wątki pozwalają programowi działać wydajniej, robiąc wiele rzeczy jednocześnie.
Wątki mogą być używane do wykonywania skomplikowanych zadań w tle bez przerywania głównego programu.
Tworzenie wątku
Istnieją dwa sposoby tworzenia wątku.
Można go utworzyć rozszerzając Thread
klasę i nadpisując jej run()
metodę:
Rozszerz składnię
public class Main extends Thread { public void run() { System.out.println("This code is running in a thread");
}}
Innym sposobem na stworzenie wątku jest zaimplementowanie Runnable
interfejsu:
Implementuj składnię
public class Main implements Runnable {
public void run() {
System.out.println("This code is running in a thread");
}
}
Uruchomione wątki
Jeśli klasa rozszerza Thread
klasę, wątek można uruchomić, tworząc instancję klasy i wywołując jej start()
metodę:
Przykład rozszerzenia
public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
Jeśli klasa implementuje Runnable
interfejs, wątek można uruchomić, przekazując instancję klasy do konstruktora obiektu, a następnie wywołując metodę Thread
wątku
:start()
Przykład implementacji
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
Różnice między „rozszerzaniem” a „wdrażaniem” wątków
Główna różnica polega na tym, że kiedy klasa rozszerza klasę Thread, nie można rozszerzyć żadnej innej klasy, ale implementując interfejs Runnable, możliwe jest rozszerzenie również z innej klasy, na przykład: class MyClass extends OtherClass implements Runnable
.
Problemy ze współbieżnością
Ponieważ wątki działają w tym samym czasie, co inne części programu, nie ma możliwości sprawdzenia, w jakiej kolejności będzie wykonywany kod. Gdy wątki i program główny odczytują i zapisują te same zmienne, wartości są nieprzewidywalne. Problemy, które z tego wynikają, nazywane są problemami współbieżności.
Przykład
Przykładowy kod, w którym wartość zmiennej kwoty jest nieprzewidywalna:
public class Main extends Thread { public static int amount = 0; public static void main(String[] args) { Main thread = new Main(); thread.start(); System.out.println(amount); amount++; System.out.println(amount);
}public void run() { amount++;
}}
Aby uniknąć problemów ze współbieżnością, najlepiej udostępniać jak najmniej atrybutów między wątkami. Jeśli atrybuty muszą być współużytkowane, jednym z możliwych rozwiązań jest użycie isAlive()
metody wątku w celu sprawdzenia, czy wątek zakończył działanie przed użyciem jakichkolwiek atrybutów, które wątek może zmienić.
Przykład
Użyj isAlive()
, aby zapobiec problemom ze współbieżnością:
public class Main extends Thread { public static int amount = 0; public static void main(String[] args) { Main thread = new Main(); thread.start(); // Wait for the thread to finish while(thread.isAlive()) { System.out.println("Waiting...");
}// Update amount and print its value System.out.println("Main: " + amount); amount++; System.out.println("Main: " + amount);
}public void run() { amount++;
}}