Ce este un fir?

Un fir este un proces ușor. Orice proces poate avea mai multe fire de rulare în el.

De exemplu, într-un browser web, putem avea un fir care va încărca interfața utilizatorului și un alt fir care va prelua de fapt toate datele care trebuie afișate în acea interfață.

Ce este MultiThreading?

Multithreading ne permite să rulăm mai multe fire simultan.

De exemplu, într-un browser web, putem avea un fir care tratează interfața cu utilizatorul și, în paralel, putem avea un alt fir care preia datele care trebuie afișate.

Deci, multi-threading îmbunătățește capacitatea de reacție a unui sistem.

Ce este simultanitatea?

Concurența în contextul firelor ne permite să rulăm mai multe fire în același timp.

Dar se execută într-adevăr firele în același timp?

Sisteme cu un singur nucleu

Thread Scheduler furnizat de JVM decide ce fir rulează la un moment dat. Planificatorul oferă o mică felie de timp fiecărui fir.

Deci, la un moment dat, avem un singur fir care rulează de fapt în procesor. Dar, din cauza tranșării timpului, avem senzația că mai multe fire rulează în același timp.

Sisteme multi core

Chiar și în mai multe sisteme de bază este implicat programatorul de fire. Dar, deoarece avem mai multe nuclee, putem avea de fapt mai multe fire care rulează exact în același timp.

De exemplu, dacă avem un sistem dual core, atunci putem avea 2 fire care rulează exact în același timp. Primul fir va rula în primul nucleu, iar al doilea fir va rula în al doilea nucleu.

De ce este nevoie de Multithreading?

Multithreading ne permite să îmbunătățim capacitatea de reacție a unui sistem.

De exemplu, într-un browser web, dacă totul ar rula într-un singur fir, atunci sistemul nu va răspunde de fiecare dată când datele vor fi preluate pentru a fi afișate. De exemplu, dacă sunt necesare 10 secunde pentru a prelua datele, atunci în acele 10 secunde nu vom putea face nimic altceva în browserul web, cum ar fi deschiderea unor file noi sau chiar închiderea browserului web.

Deci, rularea diferitelor părți ale unui program în diferite fire simultan ajută la îmbunătățirea capacității de reacție a unui sistem.

Cum se scrie programe cu mai multe fire în Java

Putem crea fire în Java folosind următoarele

  • Extinderea clasei de fire
  • Implementarea interfeței rulabile
  • Implementarea interfeței apelabile
  • Prin utilizarea cadrului executor împreună cu sarcini executabile și apelabile

Vom analiza calitățile și cadrul executorului într-un blog separat. În acest articol mă voi concentra în principal pe extinderea clasei de fire și implementarea interfeței rulabile.

Extinderea clasei de fire

Pentru a crea o bucată de cod care poate fi rulată într-un thread, creăm o clasă și apoi extindem fir clasă. Sarcina realizată de această bucată de cod trebuie introdusă în alerga() funcţie.

În codul de mai jos puteți vedea asta muncitor este o clasă care extinde fir clasă, iar sarcina de a tipări numerele de la 0 la 5 se face în interiorul alerga() funcţie.

class Worker extends Thread {

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

}

În codul de mai sus Thread.currentThread (). GetName () este folosit pentru a obține numele firului curent care rulează codul.

Pentru a crea un fir, trebuie doar să creăm o instanță a clasei muncitoare. Și apoi putem începe firul utilizând start() funcţie.

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

	}
}

În codul de mai sus, creăm 3 fire (t1, t2 și t3) din clasa lucrător. Apoi începem firele folosind start() funcţie.

Iată codul final pentru crearea unui fir prin extinderea unei clase de fire:

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

	}
}

Iată rezultatul obținut prin rularea codului de mai sus:

Ieșire Thread Class

Puteți vedea că toate cele 3 fire au imprimat numerele de la 0 la 5.

De asemenea, puteți vedea clar din ieșire că cele 3 fire nu rulează într-o anumită secvență

Implementarea interfeței Runnable

Pentru a crea o bucată de cod care poate fi rulată într-un thread, creăm o clasă și apoi implementăm alergabil interfață. Sarcina realizată de această bucată de cod trebuie introdusă în alerga() funcţie.

În codul de mai jos puteți vedea asta RunnableWorker este o clasă care implementează alergabil , iar sarcina de a tipări numerele de la 0 la 4 se face în interiorul alerga() funcţie.

class RunnableWorker implements Runnable{

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

Pentru a crea un thread, mai întâi trebuie să creăm o instanță de RunnableWorker care implementează alergabil interfață.

Apoi putem crea un nou fir prin crearea unei instanțe a fir clasă și trecând instanța de RunnableWorker ca argument. Acest lucru este indicat în codul de mai jos:

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

	}

}

Codul de mai sus creează o instanță rulabilă r. Apoi creează 3 fire (t1, t2 și t3) și trece r ca argument la cele 3 fire. Apoi start() funcția este utilizată pentru a porni toate cele 3 fire.

Iată codul complet pentru crearea unui thread prin implementarea interfeței rulabile:

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

	}

}

La executarea codului de mai sus, vom obține următoarea ieșire. Secvența de ieșire se va schimba de fiecare dată când este rulat codul.

Ieșire interfață executabilă

Implementarea interfeței rulabile este o opțiune mai bună decât extinderea clasei de fire, deoarece putem extinde o singură clasă, dar putem implementa mai multe interfețe în Java.

Interfață rulabilă în Java 8

În Java 8, interfața rulabilă devine un fișier FunctionalInterface deoarece are o singură funcție, alerga().

Codul de mai jos arată cum putem crea o instanță rulabilă în 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();
	}

}

Aici, în loc să creăm o clasă și apoi să implementăm interfața rulabilă, putem folosi direct o expresie lambda pentru a crea o instanță rulabilă așa cum se arată mai jos:

Runnable r = () -> {
        for (int i = 0; i <= 4; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    };

Cod

Codul din acest articol este disponibil în următoarea repo GitHub: https://github.com/aditya-sridhar/basic-threads-demo

Felicitări ?

Acum știți cum să creați fire prin extinderea clasei de fire și prin implementarea interfeței rulabile.

Voi discuta despre ciclul de viață și provocările firului în timp ce folosesc fire în următoarea mea postare pe blog.

Site-ul meu: https://adityasridhar.com/

Simțiți-vă liber să vă conectați cu mine pe LinkedIn sau urmează-mă Stare de nervozitate