Threads en Java (Livre Software engineering: chapitre 9) - PowerPoint PPT Presentation

1 / 51
About This Presentation
Title:

Threads en Java (Livre Software engineering: chapitre 9)

Description:

objet actif) Ecrire le code qui permet l'objet actif de lire le premier d'un ensemble de listeners qui re oit un signal en effectuant l'appel ... – PowerPoint PPT presentation

Number of Views:55
Avg rating:3.0/5.0
Slides: 52
Provided by: Petitp5
Category:

less

Transcript and Presenter's Notes

Title: Threads en Java (Livre Software engineering: chapitre 9)


1
Threads en Java(Livre Software engineering
chapitre 9)
2
Rappel
Thread
Thread
start()
extends Thread/ implement Runnable
extends Thread/ implement Runnable
Attributes

méthodeA()
méthodeA()
méthodeB()
méthodeB()
run()
run()
Attention !
3
Réentrance
thread 1
thread 2 x
attribute
attribute attribute 1
x x1 attribute x
incrément perdu
4
Singleton partagé par deux threads
Lutilisation du singleton par deux threads
proposée au début du cours était une erreur. Bien
quil utilisait id, une instruction qui paraît
atomique, pour créer différents ids, nous avons
vu sur une station dans laquelle les hyperthreads
étaient actifs, que les deux threads obtenaient
la même valeur !!! Cet id était incrémenté,
mais une seule fois, après le passage des deux
threads. Le problème vient de la JVM, qui prend
les variables dans son ALU pour les manipuler
! Il faut donc utiliser les protections
indiquées dans les prochains slides.
5
Protection au moyen dun objet unique
thread 1 thread 2
class Xxx Object o new Object()
public void methodeB() synchronized (o)
// one thread at a time
attribute attribute 1 La
méthode run() pourrait être une méthode de la
classe Xxxx
6
Protection au moyen de lobjet englobant
thread 1 thread 2
class Xxx public synchronized void
methodeB() attribute
attribute 1 // lobjet unique de
protection est lobjet qui contient methodeB() .
Il doit être instancié. Pas daccès static.
7
Wait - notify
thread 1
thread 2 1
wait ()
notify ()
2 3
8
Wait - notifyAll
thread 1
thread 2 1
wait ()
notifyAll () 2
1
wait() 3

3
notify ne redémarre quun
thread,
choisi on ne sait pas comment
9
Wait et notify doivent être placés dans un bloc
synchronized(Sémaphore sans mémoire)
class Sem public synchronized void kick ()
notify() public synchronized void
stop () try wait()
catch (InterruptedException ie)
// ou utiliser un autre objet commun
10
Canal input(Sémaphore à mémoire)
Channel channel new Channel() class Channel
LinkedList list new LinkedList()
public synchronized void put (Object obj)
list.addLast(obj) notifyAll()
Pas dinterférences de plusieurs threads dans
la méthode synchronisée
? Ne peuvent pas être séparées
11
Canal output
Channel channel new Channel() class Channel
. . . public synchronized Object
get () while (list.size()0)
try wait()
catch (InterruptedException ie) return
list.remove(0) // get the int stored in
Integer
Ne peuvent pas être séparées
12
Utilisation du canal
Channel channel new Channel() public void run
() // object avec thread
1 for (int i0ilt30i)
System.out.println("T1"i)
channel.put(new Integer(i)) public void
run () // object avec
thread 2 for () int j
((Integer)channel.get()).intValue()
System.out.println(" T2 "j)
13
Les points importants receveur
Le wait doit placé être dans une bou-cle, car le
donateur peut démarrer plusieurs threads. Cet
objet-ci risque dêtre réveillé alors quil ny a
plus de données
Waiting
non
Donnéedisponible?
Il ne faut pas quun autre thread puisse
subtiliser la donnée après la décision.
oui
Il ne faut pas quun autre thread puisse déposer
une donnée et notifier cet objet-ci entre le
moment où il teste et le moment où il dans son
état Waiting. Le signal de notification serait
perdu sinon.
Prendre la donnée
Les manipulations du buffer doivent être
protégées.
14
Les points importants donneur
Le receveur ne doit pas pouvoir sexécuter entre
les deux actions. Sil ny a pas de receveur en
attente, la notification est perdue, mais ce
nest pas grave!
Le donateur ne doit pas sexécuter si le receveur
est dans une des zones de protection. Il doit
déposer la donnée avant de notifier le receveur
Déposer une donnée
Notifier le receveur
15
Sémaphore à compteur (côté receveur)
Plutôt que de stocker des messages, on peut
incrémenter une variable qui compte un nombre de
messages virtuels
Channel channel new Channel() class Channel
int signalValue 0 . . .
public synchronized Object awaitSignal ()
while (signalValue0) try
wait() catch
(InterruptedException ie) return
--signalValue
16
Sémaphore (côté donneur)
Channel channel new Channel() class Channel
. . . int signalValue 0 public
synchronized void signal (Object obj)
signal notifyAll()
17
Canal limité
class limitedChannel final int upperLimit
5 LinkedList llst new LinkedList()
public synchronized void put(Object obj)
while (llst.size() gt upperLimi) // wait if
full try wait()
catch (InterruptedException ie)
llst.addLast(obj) if (llst.size() 1)
notifyAll() //
notifyAll réactive tous les threads en attente.
Sil en vient // après, ils ne
seront pas bloqués avant que le canal soit vide
18
Canal limité
. . . public synchronized Object get()
while (llst.size() 0) // wait if
list empty try
wait() catch (InterruptedException
ie Object obj llst.remove(0)
if (llst.size()(upperLimit-1)) // maybe
an object was notifyAll() //
waiting to put data return obj // it
can do it now
// symmétrique du précédent transparent
19
Inversion de programmes1) basé sur des listeners
Listener
Observer partie de lapplication
Listener
Observer autre partie
20
Inversion de programmes2) basé sur des
synchronisations
Observer read1 ou read2 partie de
lapplication read2 autre partie
Listener 1
Listener 2
Comme dans lexercice sur les factories de GUI
21
Exercice
Listener
Objet avec thread ( objet actif)
Listener
Listener
Ecrire le code qui permet à lobjet actif de lire
le premier dun ensemble de listeners qui reçoit
un signal en effectuant lappel await ( new
Object listener1, listener3 )
22
Analyse de programmes multithread
(livre Software Engineering, chapitre 9)
23
Modélisation des threads
object M
T1
a
T3
synchronized
synchronized
a
T2
f
mw
mn
b
notify
wait
c
g
d
24
Conditions de transitions
  • Un ou deux threads sont dans la position b et un
    thread est en f. Dans ces conditions,
    un des threads en b peut passer proceed en c,
    en quel cas le thread en f passe en g
    simultanément.
  • un thread en f peut passer en g même sil ny a
    pas de thread en b.
  • un thread en b est bloqué jusquà ce que le
    notify soit exécuté.
  • Chaque autre transition peut être exécutée chaque
    fois quun thread est dans létat de la
    transition.

25
Une trace possible
lt a, a, f gt lt b, a, f gt lt c, a, g gt lt c, b, g
gt lt d, b, g gt
26
Toutes les traces possibles
lta, a, fgt
ltb, a, fgt
lta, b, fgt
lta, a, ggt
ltc, a, ggt
ltb, b, fgt
lta, c, ggt
lta, b, ggt
ltb, a, ggt
ltd, a, ggt
ltc, b, ggt
ltb, c, ggt
lta, d, ggt
ltb, b, ggt
3
ltd, b, ggt
ltb, d, ggt
2
1
27
Un exemple derreur
E/F
f
synchronized
synchronized
a
store
g
wait
h
notify
take
f
a
28
Graphe des états
29
Erreur
  • On peut exécuter store depuis létat lta, f, Fgt
    (cest-à-dire quon va écraser la donnée
    précédente avant quelle ait été lue)
  • Dans létat lta, g, Fgt, une donnée est disponible,
    mais le lecteur est bloqué

30
Canal limité à une case
receive
send
a
f
while (empty)
while (not empty)
wait
wait
h
c
b
g
E/F
put
get
notify
notify
31
Canal limité à une case
synchronized int receive () while
(empty) wait ( ) x get (
) notify ( )
int x synchronized void send (int x)
while (not empty) wait ( )
put (x) notify ( )
32
Graphe des états
33
Exécution alternée
a
f
set
set
notifyAll
notifyAll
while (off )
while (off )
wait
wait
h
c
b
g
on/off
on/off
reset
reset
f
a
Les threads se passent un jeton. Le thread qui
possède le jeton est en exécution jusquà ce
quil le retourne au partnaire. Il y a
rendez-vous des deux threads au moment du passage
du jeton.
34
Graphe détats
35
Réactiver un thread donné
class Trigger boolean triggered false
public Object message public synchronized
void block() while (!triggered)
try wait()
catch (InterruptedException ie)
triggered false public
synchronized void unblock() triggered
true notify()
Un objet de classe Trigger mémorise la référence
dun thread. On peut mettre cette classe dans une
queue et ainsi réactiver le premier ou nimporte
quel thread dune queue, contrairement à un
simple notify()
36
Queue dobjets actifs(objet actif objet dont
run tourne sur un thread)
Réactive ce thread
37
Attacher le Trigger au thread
class Trigger private static ThreadLocal
currentTrigger new ThreadLocal()
protected synchronized Object initialValue()
return new Trigger()
public static Trigger get()
// get the trigger of the thread
return (Trigger)currentTrigger.get()
// running currently
boolean triggered false public Object
message //
to pass messages public synchronized void
block() . . . transparent précédent . . .
public synchronized void unblock() . . .
transparent précédent . . .
En plaçant un thread dans un objet ThreadLocal,
on peut le bloquer depuis nimporte quelle
méthode, car elles peuvent toutes retrouver le
trigger.
38
Thread système / utilisateur
Le GUI est exécuté sur un thread appartenant au
système. Le listener du réseau (inputchannel) est
exécuté sur un thread de lutilisateur. On na
donc pas le droit dappeler la plupart des
fonctions du GUI depuis la méthode contenue dans
le listener du réseau. Il faut utiliser la
fonction invokeLater
39
Exemple de connexion serveur-client
Browser
Serveur
html display_Manager - tireJetons(int)
servlet Manager - tireJetons(int) -
afficheJetons()
Client
topic testTopic
cmpbean Client String nom
class LoterieGUI - display TextArea - login
TextField - tireJeton TextField display(String)
listener
1 N
cmpbean Jeton int numero attente int etat
gagnant perdant
sbean ClientBean - login(String) -
tireJeton(int)
invokeLater
class Business - login(String) - tireJeton(int)
40
Protection des threads en utilisant invokeLater
Server
41
Module client
jclient MyClient package myPackage
inputchannel inputName (topic, "MDBTopic")
String s ((TextMessage)msg).getText())
java.awt.EventQueue.invokeLater(
new Runnable()
public void run()
fsmBusiness.transition(reseau, s)
)
42
Classe en WebLang
class Business package ppp outputchannel ch
(topic, testTopic) access Remote public
Business(LoterieGUI gui)
this.gui gui public void
transition(String source, String param)
. . .
43
Finite State Machine
public void transition(String source, String
param) try switch (state)
case 0 if (source
! "username") return game
gameHome().findByName(gui.getGameName())
. . . state 1
break case 1
if (source ! "nextmove") return
state 2 break
case 2 if (source !
"done") return
game.moveTerminated() state
1 catch (Exception e)

44
Exercice
  • Créer une connexion qui gère une connexion entre
    un client Java (rich client) et un serveur.

45
Appels bloquants à TCP
Livre software Engineering, chapitre 3
46
Lecture dun socket
import java.io. import java.net. byte
buffer new bytes1000 . . . ServerSocket
daemon new ServerSocket(8080) Socket
tcpSocket daemon.accept() InputStream tcpSin
tcpSocket.getInputStream() lengthRead
tcpSin.read(buffer, 0, bLength) if (lengthRead gt
0) String str new String(buffer, 0,
lengthRead) else System.out.println("Conn
ection closed")
47
Appels non-bloquant au moyen dun thread
3 canaux 3 threads pas efficace !
Boucle sur la lecture de données
Canal limité get() put()
Application
Boucle sur la lecture de données
Canal limité get() put()
Boucle sur la lecture de données
Canal limité get() put()
Ne pas utiliser directement les wait et notify,
il est très difficile déviter toutes les
erreurs, car elles peuvent être très subtiles.
48
Gestion de n canaux avec un thread (Java.nio)
import java.nio. import java.nio.channels. imp
ort java.nio.charset. ServerSocketChannel
serverSocketChannel SocketChannel
socketChannel SelectionKey selectionKey selecti
onKey createSelectionKey() while
(selectionKey.selector().select()gt0)
// infinite
loop Set readyKeys selectionKey.selector().s
electedKeys() Iterator it
readyKeys.iterator() while (it.hasNext())
//
loop over the most recent keys try
selectionKey (SelectionKey) it.next()
if (selectionKey.isAcceptable()) //
a new client has produced a new socket
. . . else if
(selectionKey.isReadable()) // a data
socket has received data
. . . catch (IOException e)
socketChannel.close()
// something has closed the socket
it.remove()
49
Appels non bloquants (Java.nio)
// un client a produit un nouveau socket, prendre
le socket, lenregistrer et // optionnellement y
attacher un objet auxiliaire
serverSocketChannel (ServerSocketChannel)
selectionKey.channel() socketChannel
serverSocketChannel.accept()
socketChannel.configureBlocking(false)
SelectionKey socketChannelKey
socketChannel.register(selectionKey.selector()
,SelectionKey.OP_READ) socketChannelKey.attach(
someObject) // après enregistrement, larrivée
de données sera détecté dans la key
50
Appels non bloquants (Java.nio)
// un data socket a reçu des données
socketChannel (SocketChannel)
selectionKey.channel() int lengthRead
0 buffer ByteBuffer.wrap(bBuffer)
lengthRead socketChannel.read(buffer)
buffer.flip() if (lengthRead lt 0)
// lautre extrémité a fermé le
socket socketChannel.close()
else if (lengthRead gt 0)
System.out.pritln( decode(buffer),
(someOject.toString())
51
Fonctions auxiliaires
public SelectionKey createSelectionKey() throws
IOException // voir le livre ou son site
Web public String decode(ByteBuffer
byteBuffer)
throws CharacterCodingException Charset
charset Charset.forName("iso-8859-1")
CharsetDecoder decoder charset.newDecoder()
CharBuffer charBuffer decoder.decode(byteBuffer)
return charBuffer.toString()
Write a Comment
User Comments (0)
About PowerShow.com