Multithreading σε Java: Πώς να ξεκινήσετε με τα νήματα

Τι είναι το νήμα;

Ένα νήμα είναι μια ελαφριά διαδικασία. Οποιαδήποτε διαδικασία μπορεί να έχει πολλά νήματα σε αυτό.

Για παράδειγμα, σε ένα πρόγραμμα περιήγησης ιστού, μπορούμε να έχουμε ένα νήμα που θα φορτώνει τη διεπαφή χρήστη και ένα άλλο νήμα που θα ανακτά πραγματικά όλα τα δεδομένα που πρέπει να εμφανίζονται σε αυτήν τη διεπαφή.

Τι είναι το MultiThreading;

Το Multithreading μας επιτρέπει να τρέχουμε ταυτόχρονα πολλά νήματα.

Για παράδειγμα, σε ένα πρόγραμμα περιήγησης ιστού, μπορούμε να έχουμε ένα νήμα που χειρίζεται τη διεπαφή χρήστη και παράλληλα μπορούμε να έχουμε ένα άλλο νήμα που παίρνει τα δεδομένα που θα εμφανίζονται.

Έτσι, το multithreading βελτιώνει την ανταπόκριση ενός συστήματος.

Τι είναι το Concurrency;

Η ταυτόχρονη συνάφεια στο νήμα μας επιτρέπει να τρέχουμε πολλά νήματα ταυτόχρονα

Αλλά τα νήματα τρέχουν πραγματικά ταυτόχρονα;

Συστήματα ενός πυρήνα

Ο προγραμματιστής νημάτων που παρέχεται από την JVM αποφασίζει ποιο νήμα εκτελείται ανά πάσα στιγμή. Ο προγραμματιστής δίνει ένα μικρό χρονικό διάστημα σε κάθε νήμα.

Επομένως, ανά πάσα στιγμή έχουμε μόνο ένα νήμα που λειτουργεί στον επεξεργαστή. Αλλά λόγω του χρόνου που κόβουμε παίρνουμε την αίσθηση ότι πολλά νήματα τρέχουν ταυτόχρονα.

Συστήματα πολλαπλών πυρήνων

Ακόμη και σε πολλά συστήματα πυρήνα εμπλέκεται ο προγραμματιστής νημάτων. Αλλά επειδή έχουμε πολλούς πυρήνες, μπορούμε πραγματικά να έχουμε πολλά νήματα να τρέχουν την ίδια στιγμή.

Για παράδειγμα, εάν έχουμε ένα σύστημα διπλού πυρήνα, τότε μπορούμε να έχουμε 2 νήματα να τρέχουν την ίδια στιγμή. Το πρώτο νήμα θα τρέξει στον πρώτο πυρήνα και το δεύτερο νήμα θα τρέξει στον δεύτερο πυρήνα.

Γιατί είναι απαραίτητο το Multithreading;

Το multithreading μας επιτρέπει να βελτιώσουμε την ανταπόκριση ενός συστήματος.

Για παράδειγμα, σε ένα πρόγραμμα περιήγησης ιστού, αν όλα λειτουργούσαν σε ένα νήμα, τότε το σύστημα δεν θα ανταποκρίνεται καθόλου όταν ανακτώνται δεδομένα για προβολή. Για παράδειγμα, εάν χρειάζονται 10 δευτερόλεπτα για τη λήψη των δεδομένων, τότε σε αυτά τα 10 δευτερόλεπτα δεν θα μπορούμε να κάνουμε οτιδήποτε άλλο στο πρόγραμμα περιήγησης ιστού, όπως το άνοιγμα νέων καρτελών ή ακόμη και το κλείσιμο του προγράμματος περιήγησης ιστού.

Έτσι η ταυτόχρονη εκτέλεση διαφορετικών τμημάτων ενός προγράμματος σε διαφορετικά νήματα βοηθά στη βελτίωση της απόκρισης ενός συστήματος.

Πώς να γράψετε προγράμματα πολλαπλών νημάτων σε Java

Μπορούμε να δημιουργήσουμε νήματα στην Java χρησιμοποιώντας τα ακόλουθα

  • Επέκταση της κλάσης νήματος
  • Υλοποίηση της τρέχουσας διεπαφής
  • Υλοποίηση της διεπαφής με δυνατότητα κλήσης
  • Χρησιμοποιώντας το πλαίσιο εκτέλεσης μαζί με εκτελέσιμες και καλούμενες εργασίες

Θα εξετάσουμε τα callables και το πλαίσιο εκτέλεσης σε ένα ξεχωριστό blog. Σε αυτό το άρθρο θα επικεντρωθώ κυρίως στην επέκταση της κλάσης νήματος και στην εφαρμογή της διεπαφής με δυνατότητα εκτέλεσης.

Επέκταση της κλάσης νημάτων

Για να δημιουργήσουμε ένα κομμάτι κώδικα που μπορεί να εκτελεστεί σε ένα νήμα, δημιουργούμε μια κλάση και στη συνέχεια επεκτείνουμε την κλάση του νήματος . Η εργασία που γίνεται από αυτό το κομμάτι κώδικα πρέπει να τεθεί στη λειτουργία run () .

Στον παρακάτω κώδικα μπορείτε να δείτε ότι ο εργαζόμενος είναι μια κλάση που επεκτείνει την κλάση νήματος και η εργασία εκτύπωσης αριθμών 0 έως 5 γίνεται μέσα στη λειτουργία run () .

class Worker extends Thread { @Override public void run() { for (int i = 0; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } 

Στον παραπάνω κώδικα Thread.currentThread (). GetName () χρησιμοποιείται για να πάρει το όνομα του τρέχοντος νήματος που εκτελεί τον κώδικα.

Για να δημιουργήσουμε ένα νήμα , πρέπει απλώς να δημιουργήσουμε μια παρουσία της εργατικής τάξης. Και μετά μπορούμε να ξεκινήσουμε το νήμα χρησιμοποιώντας τη συνάρτηση start () .

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(); } } 

Στον παραπάνω κώδικα, δημιουργούμε 3 νήματα (t1, t2 και t3) από την εργατική τάξη. Τότε ξεκινάμε τα νήματα χρησιμοποιώντας τη συνάρτηση start () .

Εδώ είναι ο τελικός κώδικας για τη δημιουργία ενός νήματος επεκτείνοντας μια κλάση νήματος:

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(); } } 

Εδώ είναι η έξοδος που λαμβάνουμε εκτελώντας τον παραπάνω κώδικα:

Έξοδος κλάσης νημάτων

Μπορείτε να δείτε ότι και τα 3 νήματα έχουν εκτυπώσει τους αριθμούς από 0 έως 5.

Μπορείτε επίσης να δείτε καθαρά από την έξοδο ότι τα 3 νήματα δεν εκτελούνται με κάποια συγκεκριμένη ακολουθία

Implementing the Runnable Interface

In order to create a piece of code which can be run in a thread, we create a class and then implement the runnable interface. The task being done by this piece of code needs to be put in the run() function.

In the below code you can see that RunnableWorker is a class which implements runnable interface, and the task of printing numbers 0 to 4 is being done inside the run() function.

class RunnableWorker implements Runnable{ @Override public void run() { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } 

In order to create a thread, first we need to create an Instance of RunnableWorker which implements the runnable interface.

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/

Μη διστάσετε να συνδεθείτε μαζί μου στο LinkedIn ή να με ακολουθήσετε στο Twitter