Mi az a szál?
A szál könnyű folyamat. Bármely folyamatban több szál futhat.
Például egy webböngészőben rendelkezhetünk egy szálzal, amely betölti a felhasználói felületet, és egy másik szál, amely ténylegesen lekéri az összes olyan adatot, amelyet meg kell jeleníteni az adott felületen.
Mi a MultiThreading?
A többszálas szálak lehetővé teszik, hogy egyszerre több szálat fussunk.
Például egy webböngészőben van egy szálunk, amely kezeli a felhasználói felületet, és ezzel párhuzamosan lehet egy másik szálunk is, amely lekéri a megjelenítendő adatokat.
Tehát a többszálas szál javítja a rendszer reakciókészségét.
Mi az egyidejűség?
A párhuzamosság a szálak kontextusában lehetővé teszi számunkra, hogy egyszerre több szálat fussunk.
De tényleg egyszerre futnak a szálak?
Egymagos rendszerek
A szál ütemező által nyújtott JVM eldönti, hogy melyik szál fut bármikor. Az ütemező kis szeletet ad az egyes szálaknak.
Tehát bármikor csak egy szálunk van, amely valójában fut a processzorban. De az idő szeletelése miatt az az érzésünk, hogy egyszerre több szál fut.
Többmagos rendszerek
Még több magos rendszerekben is részt vesz a menetütemező. De mivel több magunk van, valójában több szál futhat pontosan ugyanabban az időben.
Például, ha kétmagos rendszerünk van, akkor 2 szál futhat pontosan ugyanabban az időben. Az első szál az első magban, a második szál pedig a második magban fog futni.
Miért van szükség többszálas szálra?
A többszálas szál lehetővé teszi számunkra, hogy javítsuk a rendszer reakciókészségét.
Például egy webböngészőben, ha minden egyetlen szálon fut, akkor a rendszer teljesen nem reagál, amikor az adatokat lekérik a megjelenítéshez. Például, ha az adatok lekérése 10 másodpercet vesz igénybe, akkor ebben a 10 másodpercben semmi mást nem tehetünk a webböngészőben, például új lapok megnyitásával vagy akár a webböngésző bezárásával.
Tehát a program különböző részeinek egyidejű futtatása különböző szálakban elősegíti a rendszer reakciókészségének javítását.
Hogyan lehet többszálú programokat írni Java-ban
A Java segítségével az alábbiak segítségével hozhatunk létre szálakat
- A szálosztály kiterjesztése
- A futható felület megvalósítása
- A hívható felület megvalósítása
- A végrehajtó keretrendszer futtatható és hívható feladatokkal együtt
A hívhatóakat és a végrehajtó keretrendszert külön blogban fogjuk megvizsgálni. Ebben a cikkben elsősorban a szálosztály kibővítésére és a futható felület megvalósítására fogok összpontosítani.
A szálosztály kiterjesztése
Egy szálban futtatható kódrész létrehozásához létrehozunk egy osztályt, majd kibővítjük a szál osztályt. Az ezzel a kódrészlel végrehajtandó feladatot be kell helyezni a run () függvénybe.
Az alábbi kódban láthatja, hogy a munkavállaló egy osztály, amely kiterjeszti a szálosztályt , és a 0 és 5 közötti számok nyomtatásának feladata a run () függvényen belül történik .
class Worker extends Thread { @Override public void run() { for (int i = 0; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } }
A fenti kódban a Thread.currentThread (). A getName () segítségével megkapjuk a kódot futtató aktuális szál nevét.
Egy szál létrehozásához csak létre kell hoznunk a munkásosztály egy példányát. Ezután elindíthatjuk a szálat a start () függvény segítségével.
public class ThreadClassDemo { public static void main(String[] args) { Thread t1 = new Worker(); Thread t2 = new Worker(); Thread t3 = new Worker(); t1.start(); t2.start(); t3.start(); } }
A fenti kódban 3 szálat (t1, t2 és t3) hozunk létre a dolgozó osztályból. Ezután elindítjuk a szálakat a start () függvény segítségével.
Itt van a végső kód egy szál létrehozásához egy szál osztály kibővítésével:
class Worker extends Thread { @Override public void run() { for (int i = 0; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class ThreadClassDemo { public static void main(String[] args) { Thread t1 = new Worker(); Thread t2 = new Worker(); Thread t3 = new Worker(); t1.start(); t2.start(); t3.start(); } }
Itt van a kimenet, amelyet a fenti kód futtatásával kapunk:

Láthatja, hogy mind a 3 szál kinyomtatta a számokat 0-tól 5-ig.
A kimenetből is jól látható, hogy a 3 szál nem fut különösebb sorrendben
A futható felület megvalósítása
Egy szálban futtatható kódrész létrehozása érdekében létrehozunk egy osztályt, majd megvalósítjuk a futtatható felületet. Az ezzel a kódrészlel végrehajtandó feladatot be kell helyezni a run () függvénybe.
Az alábbi kódban láthatja, hogy a RunnableWorker egy olyan osztály, amely futtatható felületet valósít meg , és a 0–4 számok kinyomtatása a run () függvényen belül történik .
class RunnableWorker implements Runnable{ @Override public void run() { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } }
Egy szál létrehozásához először létre kell hoznunk egy RunnableWorker példányt, amely megvalósítja a futtatható felületet.
Then we can create a new thread by creating an instance of the thread class and passing the instance of RunnableWorker as the argument. This is shown in the code below:
public class RunnableInterfaceDemo { public static void main(String[] args) { Runnable r = new RunnableWorker(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } }
The above code creates a runnable instance r. Then it create 3 threads (t1, t2 and t3) and passes r as the argument to the 3 threads. Then the start() function is used to start all 3 threads.
Here is the complete code for creating a thread by implementing the runnable interface:
class RunnableWorker implements Runnable{ @Override public void run() { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class RunnableInterfaceDemo { public static void main(String[] args) { Runnable r = new RunnableWorker(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } }
On running the above code, we will get the following output. The sequence of the output will change every time the code is run.

Implementing the runnable interface is a better option than extending the thread class since we can extend only one class, but we can implement multiple interfaces in Java.
Runnable Interface in Java 8
In Java 8, the runnable interface becomes a FunctionalInterface since it has only one function, run().
The below code shows how we can create a runnable instance in Java 8.
public class RunnableFunctionalInterfaceDemo { public static void main(String[] args) { Runnable r = () -> { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } }; Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } }
Here, instead of creating a class and then implementing the runnable interface, we can directly use a lambda expression to create a runnable instance as shown below:
Runnable r = () -> { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } };
Code
The code in this article is available in the following GitHub repo: //github.com/aditya-sridhar/basic-threads-demo
Congrats ?
You now know how to create threads by extending the thread class and by implementing the runnable interface.
I will discuss the thread life cycle and challenges while using threads in my next blog post.
My Website: //adityasridhar.com/