Sunteți pe pagina 1din 16

Fire de execuție (Threads)

Limbajul Java suportă nativ noțiunea de fir de execuție (thread), adică mai multe clase ce
rulează în paralel, dar care fac parte din aceeași aplicație. Există două moduri de
implementare al unui fir de execuție:

 prin extinderea clasei java.lang.Thread;


 prin implementarea interfeței java.lang.Runnable.

Clasa Thread ca și interfața Runnable definesc o metodă numită run(). Această metodă este
metoda de start pentru thread-ul nou, analog metodei public static void main(String[]) pentru
thread-ul principal. Această metodă run() poate fi apelată în două moduri:

 apelând direct metoda run(), în care caz execuția se face ca un apel obișnuit de
metodă;
 apelând metoda start(), care pornește un thread nou care va începe execuția cu metoda
run().

Crearea și pornirea firelor de executare

Clasele și interfețele necesare utilizării firelor de executare în limbajul Java sunt incluse în
pachetul java.lang.Thread.

Un fir de executare poate fi creat prin două metode:


 extinderea clasei Thread
 implementarea interfeței Runnable

În ambele variante, trebuie redefinită/implementată metoda void run(), scriind în cadrul


său secvența de cod pe care dorim să o executăm pe un fir separat.

Exemple:

 prin extinderea clasei Thread

class FirDeExecutare extends Thread {


………………………………………
@Override
public void run() {
secvența de cod asociată firului de executare
}
}
………………………………………
FirDeExecutare f = new FirDeExecutare(); // firul nu pornește
automat!
f.start(); //trebuie apelată metoda start() care va invoca metoda
run()!
 prin implementarea interfeței funcționale Runnable

class FirDeExecutare implements Runnable {


………………………………………
@Override
public void run() {
secvența de cod asociată firului de executare
}
}
………………………………………
FirDeExecutare f = new FirDeExecutare(); // firul nu pornește
automat!
Thread t = new Thread(f);
t.start(); //trebuie apelată metoda start() care va invoca metoda
run()!

Atenție, pentru lansarea unui fir de executare, indiferent de modalitatea în care acesta a fost
creat, trebuie apelată metoda start(), care mai întâi va crea contextul necesar unui nou fir
de executare (stiva proprie, setul de regiștrii etc.) și apoi va executa metoda run() în cadrul
noului fir. Dacă am apela direct metoda run(), atunci aceasta ar fi executată ca o metodă
obișnuită, în cadrul firului curent!

Exemplu 1
Clasa FirDeExecutare utilizează un fir de executare pentru a afișa pe ecran de 10 de ori
un caracter c primit prin intermediul constructorului clasei:

class FirDeExecutare extends Thread


{
char c;

public FirDeExecutare(char c)
{
this.c = c;
}

@Override
public void run()
{
for(int i = 0; i < 10; i++)
System.out.print(c + " ");
}
}
În clasa Test_Thread vom lansa în executare două fire, unul care va afișa cifra 1 și unul
care va afișa cifra 2, iar în metoda main(), după lansarea celor două fire, vom afișa de 10
ori cifra 0:

public class Test_Thread


{
public static void main(String[] args)
{
FirDeExecutare fir_1 = new FirDeExecutare('1');
FirDeExecutare fir_2 = new FirDeExecutare('2');

fir_1.start();
fir_2.start();
// fir_1.run();
// fir_2.run();
for(int i = 0; i < 10; i++)
System.out.print("0 ");
System.out.println();
}
}
Rulând programul de mai sus de mai multe ori, pe ecran se vor afișa diverse combinații
aleatorii formate din cifrele 0, 1 și 2, în care fiecare cifră apare de exact 10 de ori.

Practic, în acest program sunt executate concurent 3 fire (fir_1, fir_2 și firul principal -
cel asociat metodei main()), pe care planificatorul le execută într-un mod aleatoriu, astfel:
fiecare fir este executat o perioadă de timp, după care el este suspendat și se trece la
executarea altui fir, până când toate cele 3 fire își vor încheia executarea.

Dacă am înlocui instrucțiunile fir_1.start() și fir_2.start() cu fir_1.run()


și fir_2.run(), pe ecran se va afișa întotdeauna combinația 1 1 ... 1 2 2 ... 2
0 0 ... 0, fiecare cifră de câte 10 de ori, deoarece metoda run() nu va fi executată pe
un fir separat, ci va fi executată ca o metodă obișnuită, în firul principal al aplicației!
Tema
Sa se testeze si sa se discute rezultatul...

Exemplu 2

import java.awt.*;
public class AlternareCulori extends java.applet.Applet implements Runnable {
Font f=new Font("TimesRoman",Font.BOLD,30);
Color culori[]=new Color[50];
Thread executabil;
public void start() {
if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}
public void stop() {
executabil=null;
}
public void run() {
float c=0;
for (int i=0;i<culori.length;i++) {
culori[i]=Color.getHSBColor(c,(float)1.0,(float)1.0);
c+=.02;
}
int i=0;
Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
setForeground(culori[i]);
repaint();
i++;
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
if (i==culori.length) i=0;
}
}
public void paint(Graphics ecran) {
ecran.setFont(f);
ecran.drawString("Priviti textul!",10,50);
ecran.drawString("Culoarea se modifica!",10,80);
}
}
import java.awt.*;
import java.util.*;
public class CeasDigital extends java.applet.Applet implements Runnable {
Font fontul=new Font ("TimesRoman",Font.BOLD,24);
Date data;
Thread executabil;
public void start() {
if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}
public void stop() {
if (executabil!=null) {
executabil=null;
}
}
public void run() {
Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
repaint();
try{
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}

Metodele start() si stop() au rolul de a porni si respectiv opri firul de executie.


Metoda run() - realizeaza toata animatia. Aici vom avea si “periculosul” ciclu while de mai
sus; primul lucru facut in ciclu este apelarea repaint() pentru redesenarea ferestrei.
sleep() a metoda a clasei Thread determina o pauza in executie.
Daca nu s-ar folosi aceasta metoda appletul ar rula la viteza maxima, lucru care poate sa nu
fie conform cu dorinta programatorului. Instructiunile try si catch vor apare aici pentru
tratarea erorilor si pentru moment le putem ignora.
Metoda paint() a appletului creaza o noua instanta a clasei Date - pentru folosirea acestei
clase trebuie sa o importam, ea fiind inclusa in java.util. De asemenea apare si metoda
toString() a clasei Date, necesara pentru afisarea ca sir a datei si orei. La fiecare apelare a
metodei paint() vom avea astfel un nou obiect Date care va tine ora si data curente.

CREAREA DE INTERFETE GRAFICE PENTRU APPLETURI


Realizarea unei astfel de interfete in limbajul Java se bazeaza in principal pe biblioteca AWT
(Abstract Windowing Toolkit), care contine un set de clase pentru crearea si folosirea unor astfel
de interfete grafice pentru utilizator.

import java.awt.TextField;
public class texts extends java.applet.Applet
{
public void init ()
{
add (new TextField());
add (new TextField (25));
add (new TextField ("Empty String"));
add (new TextField ("Empty String", 40));
}}

import java.awt.*;
public class Lista_derulanta extends java.applet.Applet {
List lista=new List(4,true);
Label eticheta=new Label("Selectati limbajele de programare cunoscute: ");
public void init() {
add(eticheta);
lista.add("C++");
lista.add("C#");
lista.add("Java");
lista.add("Phpt");
lista.add("Pyton");
lista.add("Visual Basic");
add(lista); } }
import java.awt.*;
import java.applet.*;
public class RadioButtonTest extends Applet
{
public void init( )
{
CheckboxGroup chkgrp = new CheckboxGroup ( );

Checkbox chkRed,chkBlue,chkYellow,chkGreen,chkOrange;

chkRed = new Checkbox("Red", chkgrp, false);


chkBlue = new Checkbox("Blue", chkgrp, false);
chkYellow = new Checkbox("Yellow", chkgrp, false);
chkGreen = new Checkbox("Green", chkgrp, true);
chkOrange = new Checkbox("Orange", chkgrp, false);

add(chkRed);
add(chkBlue);
add(chkYellow);
add(chkGreen);
add(chkOrange);
}
}
import java.applet.Applet;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Graphics;
import java.awt.event.*;
public class RadioButtonEx extends Applet implements ItemListener{
CheckboxGroup gr = null;
public void init(){
//create group
gr = new CheckboxGroup();

//create checkboxes and add to group


Checkbox java = new Checkbox("Java", gr, true);
Checkbox cpp = new Checkbox("C++", gr, false);
Checkbox vb = new Checkbox("VB", gr, false);
Checkbox vp = new Checkbox("PHP", gr, false);
Checkbox vpy = new Checkbox("Pyton", gr, false);
//add radio buttons
add(java);
add(cpp);
add(vb);
add(vp);
add(vpy);
//add listeners
java.addItemListener(this);
cpp.addItemListener(this);
vb.addItemListener(this);
vp.addItemListener(this);
vpy.addItemListener(this);
}
public void itemStateChanged(ItemEvent ie) {
repaint();
}
public void paint(Graphics g){
/*
* To get selected radio button, use
* Checkbox getSelectedCheckbox()
* method of CheckboxGroup class.
*/
Checkbox chk = gr.getSelectedCheckbox();
g.drawString(chk.getLabel() + " is selected", 10 ,70);
}
}

SUPRAFETE DE DESENARE

import java.awt.*;
public class Canvas extends java.applet.Applet {
GridLayout admin=new GridLayout(1,1);
canvasNou suprafata=new canvasNou();
public void init() {
setLayout(admin);
add(suprafata);
}
}
class canvasNou extends java.awt.Canvas {
public void paint(Graphics ecran) {
int x=getSize().width/2;
int y=getSize().height/2;
System.out.println("x = "+x);
System.out.println("y = "+y);
ecran.setColor(Color.blue);
ecran.drawLine(x-10,y,x-2,y);
ecran.setColor(Color.red);
ecran.drawLine(x+10,y,x+2,y);
ecran.setColor(Color.green);
ecran.drawLine(x,y-10,x,y-2);
ecran.setColor(Color.magenta);
ecran.drawLine(x,y+10,x,y+2);
}
}
Aplicatie - Lab_7_LoterieNumar

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.ChronoUnit;

public class Lab_7_LoterieNumar extends Applet implements ActionListener {

Font fontTip1 = new Font("Verdana", Font.BOLD, 20);


Font fontTip2 = new Font("Calibri", Font.BOLD, 30);
Font fontTip3 = new Font("Vladimir Script", Font.BOLD, 40);
FontMetrics fm = getFontMetrics(fontTip3);
Label label1, label2, label3, label4, label5, label6, label7, label8;
TextField intrare;
Button continuare;
int numarAleator=0, numarPropus=0, incercari=5;
LocalDateTime dataAziCompleta = LocalDateTime.now();
LocalTime momentPornire = LocalTime.now();
LocalDate dataAzi = dataAziCompleta.toLocalDate();
Month lunaAzi = dataAziCompleta.getMonth();
int ziAzi = dataAziCompleta.getDayOfMonth();
int oraAzi = dataAziCompleta.getHour();
int minutAzi = dataAziCompleta.getMinute();
int secundaAzi = dataAziCompleta.getSecond();
String oraCompleta = oraAzi+":"+minutAzi+":"+secundaAzi;

public void init() {


numarAleator= (int)(20*Math.random()+1);

setLayout(new GridLayout(15,1));
setBackground(Color.ORANGE);
setSize(600,600);

System.out.println("Data completa pentru azi: "+dataAziCompleta);


System.out.println("Data azi: "+dataAzi);
System.out.println("Luna curenta: "+lunaAzi+" Ziua curenta: "+ziAzi);
System.out.println("Ora exacta... calculata de noi :):
"+oraAzi+":"+minutAzi+":"+secundaAzi);
System.out.println("Ora exacta din clasa LocalTime: "+momentPornire);

label1 = new Label("Ghiciti numarul la loteria noastra");


label1.setFont(fontTip1);
label1.setForeground(Color.BLUE);
label1.setAlignment(label1.CENTER);
add(label1);

label2 = new Label("Trebuie sa ghiciti un numar intre 1 si 20 - aveti 5 incercari");


label2.setAlignment(label2.CENTER);
add(label2);

intrare = new TextField(5);


intrare.setFont(fontTip2);
add(intrare);

label3 = new Label("");


label3.setAlignment(label3.CENTER);
add(label3);

label4 = new Label("");


label4.setAlignment(label4.CENTER);
label4.setFont(fontTip1);
label4.setForeground(Color.MAGENTA);
add(label4);
label5 = new Label("");
label5.setAlignment(label5.CENTER);
add(label5);

label6 = new Label("");


label6.setAlignment(label6.CENTER);
add(label6);

label7 = new Label("Ora de start: "+oraCompleta);


label7.setAlignment(label7.CENTER);
add(label7);

continuare = new Button("Joc nou");


continuare.setEnabled(false);
continuare.setFont(fontTip2);
add(continuare);

label8 = new Label("");


label8.setAlignment(label8.CENTER);
label8.setFont(fontTip1);
add(label8);

intrare.addActionListener(this);
continuare.addActionListener(this);
}

public void numarIncercari() {


if (incercari>1) {
label6.setText("Mai ai "+ --incercari + " incercari.");
label3.setText("Incearca alt numar: ");
label6.setFont(fontTip1);
}
else {
label6.setText("Ooops... gata, s-a terminat!");
label8.setText("Numarul castigator la loto era: "+numarAleator);
label6.setFont(fontTip1);
intrare.setEnabled(false);
continuare.setEnabled(true);
continuare.requestFocus();
repaint();
}
}

public void clear() {


intrare.setText("");
}

public void paint(Graphics g) {


if (numarAleator==numarPropus && incercari>1) {
g.setFont(fontTip3);
g.setColor(new Color(150,55,25));
g.drawString("Ai CASTIGAT!",170,440);
g.drawString("...experienta",170,490);
}
else if (incercari==1) {
g.setFont(fontTip3);
g.setColor(new Color(150,55,25));
g.drawString("S-a terminat!", 130, 400);
}
else {
g.setFont(fontTip3);
g.setColor(new Color(150,55,25));
g.drawString("Start joc",(getSize().width-fm.stringWidth("Start joc"))/2,500);
}
}

public void actionPerformed(ActionEvent e){


numarPropus = Integer.parseInt(intrare.getText());
showStatus("Aplicatie ca exemplu didactic :)");

if (e.getSource()==continuare) {
numarAleator = (int)(20*Math.random()+1);
continuare.setEnabled(false);
intrare.setEnabled(true);
label3.setText("");
label4.setText("");
label5.setText("");
label6.setText("");
label7.setText("");
label8.setText("");
incercari = 5;
clear();
repaint();
}

if(e.getSource()==intrare) {
if (numarAleator>numarPropus) {
label4.setText("Introduceti un numar mai mare decat " + numarPropus + " !");
numarIncercari();
intrare.requestFocus();
intrare.selectAll();
}
else if (numarAleator<numarPropus) {
label4.setText("Introduceti un numar mai mic decat " + numarPropus + " !");
numarIncercari();
intrare.requestFocus();
intrare.selectAll(); }
else {

LocalDateTime dataFinalCompleta = LocalDateTime.now();


LocalTime momentOprire = LocalTime.now();
int oraFinal = dataFinalCompleta.getHour();
int minutFinal = dataFinalCompleta.getMinute();
int secundaFinal = dataFinalCompleta.getSecond();
String oraFinalCompleta = oraFinal+":"+minutFinal+":"+secundaFinal;
long durataOre = ChronoUnit.HOURS.between(momentPornire, momentOprire);
long durataMinute = ChronoUnit.MINUTES.between(momentPornire,
momentOprire);
long durataSecunde = ChronoUnit.SECONDS.between(momentPornire,
momentOprire);
long durataMilisecunde = ChronoUnit.MILLIS.between(momentPornire,
momentOprire);
long durataNanosecunde = ChronoUnit.NANOS.between(momentPornire,
momentOprire);

label4.setText("Ai nimerit! Felicitari si fugi sa joci la loto!");


label3.setText("");
//label5.setText("");
label5.setText("Ora de final: "+oraFinalCompleta+". Timp total:
"+durataOre+":"+durataMinute+":"+durataSecunde+"."+durataMilisecunde+"."+durataNanos
ecunde);
//label6.setText("");
label7.setText("");
intrare.setEnabled(false);
continuare.setEnabled(true);
incercari = 5;
repaint();
}
}
}
}

S-ar putea să vă placă și