Многопоточност в Java: Как да започнем с нишки

Какво е нишка?

Конецът е лек процес. Всеки процес може да има множество нишки, работещи в него.

Например в уеб браузър можем да имаме една нишка, която ще зареди потребителския интерфейс, и друга нишка, която всъщност ще извлече всички данни, които трябва да бъдат показани в този интерфейс.

Какво е MultiThreading?

Многопоточността ни позволява да изпълняваме едновременно множество нишки.

Например в уеб браузър можем да имаме една нишка, която обработва потребителския интерфейс, и успоредно с това може да имаме друга нишка, която извлича данните за показване.

Така че многопоточността подобрява отзивчивостта на системата.

Какво е паралелност?

Паралелността в контекста на нишките ни позволява да изпълняваме няколко нишки едновременно.

Но темите наистина ли се изпълняват едновременно?

Едноядрени системи

В МАЧОВЕТЕ Scheduler , предоставена от JVM решава кои нишка минава във всеки даден момент. Планировщикът дава малък интервал от време за всяка нишка.

Така че по всяко време имаме само една нишка, която всъщност работи в процесора. Но поради нарязването на времето имаме усещането, че множество нишки работят едновременно.

Многоядрени системи

Дори в множество основни системи е включен планировчикът на нишки. Но тъй като имаме множество ядра, всъщност можем да имаме няколко потока, работещи по едно и също време.

Например, ако имаме двуядрена система, тогава можем да имаме 2 нишки, работещи по едно и също време. Първата нишка ще работи в първата сърцевина, а втората нишка ще работи във втората сърцевина.

Защо е необходима Multithreading?

Многопоточността ни позволява да подобрим отзивчивостта на системата.

Например в уеб браузър, ако всичко се изпълнява в една нишка, тогава системата ще бъде напълно неотзивчива, когато данните се извличат за показване. Например, ако отнемането на данните отнема 10 секунди, тогава през тези 10 секунди няма да можем да направим нещо друго в уеб браузъра, като отваряне на нови раздели или дори затваряне на уеб браузъра.

Така че едновременното изпълнение на различни части на програма в различни нишки помага да се подобри отзивчивостта на системата.

Как да напиша многонишкови програми в Java

Можем да създадем нишки в Java, като използваме следното

  • Разширяване на класа на нишката
  • Внедряване на изпълним интерфейс
  • Внедряване на извикващия се интерфейс
  • Чрез използване на изпълнителната рамка заедно с изпълними и извикващи се задачи

Ще разгледаме извикващите и изпълнителната рамка в отделен блог. В тази статия ще се съсредоточа главно върху разширяването на класа на нишката и внедряването на изпълним интерфейс.

Разширяване на нишката клас

За да създадем парче код, което може да се изпълни в нишка, ние създаваме клас и след това разширяваме класа на нишката . Задачата, която се изпълнява от тази част от кода, трябва да бъде поставена във функцията 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