Capitolo 12
Thread
Lucidi relativi al volume:
Java – Guida alla programmazione
James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
La storia finora
I programmi sono costituiti da singoli flussi di controllo
Il flusso di controllo inizia nella prima istruzione del metodo main() e
procede istruzione per istruzione fino all'ultima istruzione del metodo
main()
Il flusso di controllo può essere passato temporaneamente ad altri
metodi con le invocazioni, ma il controllo torna a main() dopo il
completamento
I programmi con flussi di controllo singoli sono detti processi sequenziali
Single-threaded Program {
Statement 1;
Statement 2;
...
Statement k;
}
Sebbene
Alt hough t un'istruzione
he st at ement s all'interno
wit hin a single
di un
flusso
di controllo
possa
flow
of solo
cont rol
may invoke
ot her met
hods,
invocare
metodi,
t he next staltri
at ement
is notl'istruzione
execut ed unt il
chet he
segue
non
eseguita
current
st viene
at ement
complet es
finché la prima non è conclusa
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Processi
La capacità di eseguire più processi contemporaneamente è
una caratteristica importante dei moderni sistemi operativi
Un desktop utente potrebbe eseguire un browser, un IDE
di programmazione, un lettore di musica e un sistema di
preparazione dei documenti
Java supporta la creazione di programmi con flussi di
controllo concorrenti, i thread
I thread sono eseguiti in un programma e utilizzano le sue
risorse per l'esecuzione
Processi leggeri
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Processi
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Elaborazione multithread
Unit hreaded
programma
a più
A mult
program
endsthread
when allsiof it s
conclude
quando
finiscono
tutti
individual flows of cont rol (t hreads)
endi
flussi di controllo individuali (thread)
Il programma a più thread
This
mult it hreaded
avvia
il thread
A per program
delegare
st
art
s
up
t
hread
A t o assist
parte delle operazioni
del in
t
he
program's
t
ask.
Aft
er
programma. Dopo aver
st artavviato
ing t he tilhread,
t
he
program
thread, il
cont
inues wit h itcontinua
s next st atcon
ement
programma
l'istruzione successiva
Thread A {
A Statement
A Statement
...
A Statement
...
A Statement
}
Multithread Program {
Statement 1;
Statement 2;
...
Statement i;
...
Statement j;
...
Statement m;
}
1;
2;
Thread B {
B Statement 1;
B Statement 2;
n;
...
p;
Il thread
avvia
per
Thread A
A st
art s il
upthread
t hread CCt o
delegare
operazioni
assist parte
it in it sdelle
program
subt ask. del
thread.
aver
thread
Aft erDopo
st art ing
t heavviato
t hread, tilhread
C, ilAthread
A wit
continua
cont inues
h it s nextcon
l'istruzione
successiva
st at ement
Il programma
più thread
This
mult it hreadedaprogram
also avvia
anche
il
thread
B
per
delegare
st art s up t hread B t o assist in t he parte
delle operazioni
program's
t ask. Aft er del
st artprogramma.
ing t he
Dopo
aver
avviato
il thread,
t hread, t he program cont inues
wit h il
programma
continua
con
l'istruzione
it s next st at ement
successiva
B Statement q;
}
Thread C {
C Statement 1;
C Statement 2;
...
C Statement r;
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Timer e TimerTask
Tra le altre, le classi Java java.util.Timer e java.util.TimerTask
supportano la creazione e la pianificazione di thread
La classe astratta Timer possiede metodi per creare thread
dopo un ritardo specificato o in un tempo specifico
public void schedule(TimerTask task, long m)
Esegue task.run() dopo m millisecondi.
public void schedule(TimerTask task, long m, long n)
Esegue task.run() dopo m millisecondi. Poi esegue
ripetutamente task.run() ogni n millisecondi.
public void schedule(TimerTask task, Date y)
Esegue task.run() nel momento t.
Un thread può essere creato estendendo TimerTask e
specificando una definizione per il metodo astratto run()
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Esecuzione dopo un ritardo
La classe DisplayCharSequence estende TimerTask per supportare la
creazione di un thread che visualizza 20 copie del carattere
desiderato (per esempio “H”, “A” o “N”)
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Utilizzo di DisplayCharSequence
public static void main(String[] args){
DisplayCharSequence s1 =
new DisplayCharSequence('H');
DisplayCharSequence s2 =
new DisplayCharSequence('A');
DisplayCharSequence s3 =
new DisplayCharSequence('N');
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Defining DisplayCharSequence
import java.util.*;
public class DisplayCharSequence extends TimerTask {
private char displayChar;
Timer timer;
public DisplayCharSequence(char c) {
displayChar = c;
timer = new Timer();
timer.schedule(this, 0);
}
public void run() {
for (int i = 0; i < 20; ++i) {
System.out.print(displayChar);
}
timer.cancel();
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Implementazione di un metodo run()
Un'implementazione sottoclasse del metodo astratto run() di
TimerTask generalmente è divisa in due parti
La prima definisce l'azione specifica per l'applicazione che
il thread deve eseguire
La seconda termina il thread
Il thread viene terminato quando viene completata
l'azione specifica per l'applicazione
// run(): display the occurences of the character of interest
public void run() {
for (int i = 0; i < 20; ++i) {
Desired
ion ilt othread
be
Azioneact
che
System.out.print(displayChar);
performed
by t hread
deve compiere
}
Desired
actdesiderata
ion is
L'azione
è stata
timer.cancel();
complet
ed so t hread
completata;
pertanto,
}
is
canceled
il thread viene chiuso
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Esecuzione ripetuta
Esempio
Aggiornamento di un orologio ad ogni secondo
public static void main(String[] args){
SimpleClock clock = new SimpleClock();
}
public class SimpleClock extends TimerTask {
final static long MILLISECONDS_PER_SECOND = 1000;
private JFrame window = new JFrame("Clock");
private Timer timer = new Timer();
private String clockFace = "";
public SimpleClock() {
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(200, 60);
Container c = window.getContentPane();
c.setBackground(Color.white);
window.setVisible(true);
timer.schedule(this, 0, 1*MILLISECONDS_PER_SECOND);
}
public void run() {
Date time = new Date();
Graphics g = window.getContentPane().getGraphics();
g.setColor(Color.WHITE);
g.drawString(clockFace, 10, 20);
clockFace = time.toString();
g.setColor(Color.BLUE);
g.drawString(clockFace, 10, 20);
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Pianificazione di SimpleClock
timer.schedule(this, 0, 1*MILLISECONDS_PER_SECOND);
Pausa
in millisecondi
The millisecond
delay
prima della prima
before
t he t hread is
esecuzione del
firstthread
scheduled
The
numberdiof
Numero
millisecondi
milliseconds
bettra
ween
esecuzioni
delt hread
thread
runs of t he
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Esecuzione all'orario scelto
Esempio
Pianificazione di calendari a comparsa utilizzando la classe
DisplayAlert
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Utilizzo di DisplayAlert
public static void main(String[] args){
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 9);
c.set(Calendar.MINUTE, 30);
c.set(Calendar.SECOND, 0);
Date studentTime = c.getTime();
c.set(Calendar.HOUR_OF_DAY, 18);
c.set(Calendar.MINUTE, 15);
c.set(Calendar.SECOND, 0);
Date danceTime = c.getTime();
DisplayAlert alert1 = new DisplayAlert(
"Prospective student meeting", studentTime);
DisplayAlert alert2 = new DisplayAlert(
"Dance recital", danceTime);
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Defining DisplayAlert
import javax.swing.JOptionPane;
import java.awt.*;
import java.util.*;
public class DisplayAlert extends TimerTask {
private String message;
private Timer timer;
public DisplayAlert(String s, Date t) {
message = s + ": " + t;
timer = new Timer();
timer.schedule(this, t);
}
public void run() {
JOptionPane.showMessageDialog(null, message);
timer.cancel();
}
}
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Sleeping
I thread possono essere utilizzati per mettere in pausa un
programma
La classe standard java.lang.Thread possiede un metodo di
classe sleep() per mettere in pausa un flusso di controllo
public static void sleep(long n) throws InterruptedException
Mette in pausa il thread corrente per n millisecondi. Poi
lancia una InterruptedException.
Java – Guida alla programmazione - James Cohoon, Jack Davidson
Copyright © 2004 - The McGraw-Hill Companies srl
Esempio di sleeping
Codice
Date t1 = new Date();
System.out.println(t1);
try {
Thread.sleep(10000);
}
catch (InterruptedException e) {
}
Date t2 = new Date();
System.out.println(t2);
Output
Fri Jan 31 19:29:45 EST 2003
Fri Jan 31 19:29:55 EST 2003