Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Introduzione al Multithreading in Java: Note e Esercizi, Appunti di Programmazione Java

Appunti thread prima parte oop Java

Tipologia: Appunti

2018/2019

Caricato il 29/08/2019

francesco-pistorio
francesco-pistorio 🇮🇹

4.8

(8)

17 documenti

1 / 23

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
thread 1
Note su serializzazione
thread 2
serializzazione
Meccanismo per trasformare un oggetto in una serie di byte che può essere
inviata dove si desidera o memorizzata su disco e viceversa ricostruire un
oggetto dalla serie di byte.
Un oggetto è serializabile se implementa l’interfaccia (tagging) Serializable
Per evitare di serializzare specifiche instance variable le si dichiara
transient (modificatore)
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17

Anteprima parziale del testo

Scarica Introduzione al Multithreading in Java: Note e Esercizi e più Appunti in PDF di Programmazione Java solo su Docsity!

thread 1

Note su serializzazione

serializzazione

● Meccanismo per trasformare un oggetto in una serie di byte che può essere inviata dove si desidera o memorizzata su disco e viceversa ricostruire un oggetto dalla serie di byte. ● Un oggetto è serializabile se implementa l’interfaccia (tagging) Serializable ● Per evitare di serializzare specifiche instance variable le si dichiara transient (modificatore)

thread 3

Serializzazione e deserializzazione

● Per serializzare gli oggetti occorre un ObjectOutputStream costruito a partire da un OutputStream ObjectOutputStream out = new ObjectOutputStream (Files. ObjectOutput(path)); ● Su questo oggetto out si invoca il metodo writeObject( oggettoDaSerializzare ); ● Per recuperare l’oggetto dallo stream ● ObjectInputStream in = new ObjectInputStream (Files. ObjectInput(path)); ● Tipo oggettoDeserializzato = (Tipo)in.readObject(); OutputStream outStream = new FileOutputStream( filename ); ObjectOutputStream out = new ObjectOutputStream(outStream); out.writeObject(oggetto); InputStream inStream = new FileInputStream( filename ); ObjectInputStream in = new ObjectInputStream(inStream); Tipo oggetto = (Tipo) in.readObject(); Tipo oggetto

7

a cosa servono I thread?

  • Eseguire task in parallelo: in modo asincrono e concorrente
  • mantenere responsiveness di un’applicazione durante un long running task
  • permettere la cancellazione di task separabili
  • server concorrenti
    • pattern dispatcher – workers , modello tipico di molte applicazioni
    • connection manager – intrinsecamente concorrente
  • per la programmazione event-driven e listener based e pattern MVC
  • per monitorare lo stato di alcune risorse (e.g., DB) in parallelo al normale funzionamento … nota
  • alcune APIs e sistemi lo richiedono (e.g., Swing)
  • alcuni problemi sono intrinsecamente paralleli
  • come suddividere I calcoli in task concorrenti?
  • Come eseguirli in modo safe? la gestione dell’event delegation 8
  • Event Delegation: un

componente grafico delega

agli ascoltatori l’azione da

svolgere.

  • Separazione sorgenti degli

eventi dal comportamenti a essi

associato

  • ogni componente GUI può avere più di

un listener per un certo evento:

i listener

  • si registrano in una lista
  • vengono chiamati uno per volta

nell’ordine di registrazione

GESTIONE DEGLI EVENTI

Ogni componente GUI viene associato a

un ascoltatore degli eventi (un oggetto

che implementa l'opportuna interfaccia

Listener )

Event

Listener

l’azione sul componente (ad

es., click sul pulsante) genera

un evento, che è inviato

all'ascoltatore

L'ascoltatore

gestisce l'evento

9 event 10        

  • Quando un server accetta una connessione esso può generare un

nuovo thread per servire la richiesta, mentre il thread originale continua

a stare in attesa (su serverSocket.accept()) di connessioni da

altri client.

  • Questa soluzione permette di non perdere richieste di connessioni e di

servire più client che fanno richieste in parallelo.

connrction manager connrction handler

thread 13

processi e thread in java

Java ha i thread nativi: i thread sono supportati dal linguaggio

  • La classe Thread fornisce la gestione dei thread ● un processo è una istanza di JVM contiene
  • lo heap (ogni cosa che deriva da un new)
  • variabili globali : campi statici o class object condivisi da tutti gli oggetti thread ● un thread è uno stato runtime della JVM
  • runtime stack e registri memorizzati
  • Instance variable e variabili locali di un metodo restano locali al thread ● codice thread-safe può eseguire in un ambiente multithread
  • deve sincronizzare l'accesso alle risorse condivise con gli altri thread (eg. memoria) o essere rientrante 14

Thread Multipli in una Applicazione

  • ogni thread ha il suo run-time stack privato
    • se 2 thread eseguono lo stesso metodo, ciascuno avrà la sua copia delle variabili locali che i metodi usano
  • tutti i thread vedono la stessa dynamic memory / heap
    • 2 differenti thread possono agire sullo stesso oggetto e sugli stessi static field concorrentemente Main Thread Thread A Thread B Thread C start (^) start start (^) Threads may switch or exchange data/results Programma Multithread(ed)

thread 15

Le applicazioni multi-thread

Una applicazione si avvia come single-thread (non-deamon) che chiama il metodo main()

  • la JVM crea un thread object il cui task è definito dal metodo main()Un thread java può creare altri thread che condividono lo stesso programma applicativo ● La JVM
  1. avvia/start il thread
  2. il thread esegue le istruzioni del task, run, in modo sequenziale
  3. dopo aver eseguito tutte le sue istruzioni, il metodo termina con return ed il thread termina ● la JVM continua ad eseguire thread finchè
  • viene chiamato il metodo exit() della classe Runtime
  • tutti i thread (non deamon) terminano con return della chiamata run() oppure throwing an exception termina il processo

2 modi di creare un thread di esecuzione

new new start() ● Dichiarare una classe che implementa una interfaccia Runnable

  • la classe deve implementare il metodo run()
  • Una istanza della classe andrà allocata, passandola come argomento quando si crea il thread , ed avviata ● Dichiarare una classe come sottoclasse di Thread
  • Questa classe deve ridefinire il metodo run()
  • Una istanza di questa sottoclasse andrà allocata ed avviata start()

descrive un task che può essere svolto in modalità asincrona

Esegue il task

thread 19

modalità extends della classe Thread

● Creare una classe che estende direttamente la classe Thread ed override

del metodo run(): class MyThread extends Thread { … public void run(){ // thread body of execution } }

  1. Creazione di un thread: MyThread thr1 = new MyThread();
  2. avvio /start dell’esecuzione del thread: thr1.start(); //attivazione del thread ● oppure anche contestualmente: Creazione ed Esecuzione: new MyThread().start(); thread 20

modalità implements dell’interfaccia Runnable

● Creare una classe che implementa l’interfaccia Runnable ed override

del metodo run() :

class MyRunnableObject implements Runnable {

public void run(){

// thread body of execution

1. Creazione di un oggetto:

MyRunnableObject myObject = new

MyRunnableObject();

2. Creazione di un thread object:

Thread thr1 = new Thread( myObject );

3. avvio/start dell’ esecuzione:

thr1.start();

nota: I thread si possono avviare in pool tramite Executor

thread 21

…semplicemente “hello world” a confronto

public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); } } public class HelloThread extends Thread { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new HelloThread()).start(); } } ●Nota : entrambi avviano il thread con start(); qui innesta all’interno un main di avvio

class diagram

thread 25

Passi di creazione ed esecuzione del thread

  1. Invocazione del costruttore per creare/allocare l’oggetto thread
  2. Chiamata del metodo start() che esegue l’inizializzazione /configurazione del thread ed invoca il metodo run() del thread NB: se non viene invocato esplicitamente start() , il metodo run() non viene eseguito
  3. Meccanismo di esecuzione: chiamata run() ………………………………………………………………………………………….. NB: gli oggetti thread possono essere creati senza memorizzarne i riferimenti, ● non seguono le sorti dei comuni oggetti, facile preda del garbage collectorogni thread “si registra” comunque nel sistema : da qualche parte c’è un riferimento ad esso fuori dallo heap ● Il riferimento al thread verrà eliminato quando il thread termina di eseguire il suo metodo run() es. di costruttori public Thread();
  • crea un thread, numerato automaticamente, di formato Thread-n (n integer) public Thread(String threadName );
  • crea un thread di nome threadName public Thread(Runnable target )
  • Alloca un nuovo Thread object.
  • Il parametro target è l'oggetto per cui viene chiamato il metodo run() public Thread(Runnable target , String threadName )
  • run() fa il lavoro del thread. Deve essere riscritto in ogni sotto-classe di Thread o in oggetti che implementano linterfaccia Runnable
  • start()
  • Configura e avvia il thread e torna al chiamante
  • invoca run() NB: È un errore: invocare start() 2 volte per lo stesso thread public static Thread currentThread () ritorna reference al thread correntemente in esecuzione

Classe Thread del package java.lang

thread 27

es. estensione della

classe Thread

getName() countDown

Interfaccia Runnable

● l'interfaccia Runnable specifica solo il metodo run()che andrà ridefinito

  • implementata anche dalla classe Thread ● Java non supporta multiple inheritance di classi è nel caso in cui la classe che si vuole rendere multithread sia già derivata si usa realizzare una classe che implementa l'interfaccia Runnable, Multithreading per una classe già derivata
  • Implementare l'interfaccia Runnable (del package java.lang )
  • gli oggetti delle nuove classi sono oggetti Runnable
  • riscrivere (override) in questa implementazione il metodo run()
  • controlla il thread, come se derivato dalla classe Thread ,
  • Infatti la classe Thread implementa l'interfaccia Runnable ● Creare un nuovo thread usando i costruttori di Thread Thread( Runnable runnableObject ) Thread( Runnable runnableObject, String threadName )

thread 31

… A proposito dell’interfaccia Runnable

● L’unica cosa richiesta per definire una classe che implementa Runnable è la definizione del metodo run(),

  • tuttavia per poter accedere ad essa ed ai metodi di Thread (es. getName()) è necessario ottenere un riferimento esplicito al thread per mezzo del metodo Thread.currentThread() public static Thread currentThread() ● ritorna un riferimento all’oggetto Thread correntemente in esecuzione ● Gli oggetti che implementano l’interfaccia Runnable specificano semplicemente un metodo run() ma, a differenza dei Thread, non possiedono nessuna capacità multithreading ● Per produrre un thread da un oggetto Runnable è necessario creare un apposito oggetto “wrapper” Thread che lo gestisca.
  • Solo a questo punto è possibile invocare su quel thread il metodo run() che effettua l’inizializzazione ed invoca il metodo run()

java.lang.Thread

● Una applicazione si avvia come single-thread (non-deamon) che chiama il metodo main() ● Un thread java può crearne altri che condividono lo stesso programma applicativo ● La JVM continua ad eseguire thread fino a quando

  • viene chiamato il metodo exit() della classe Runtime
  • Tutti i thread (non deamon) sono terminati, con return della chiamata run()
  • oppure “ throwing an exception ” ● I thread hanno una priorità associata ● I thread possono essere marcati come deamon
  • invocando setDeamon() prima del metodo start() ● i deamon thread forniscono un servizio di uso generale in background che non condiziona la terminazione del programma

thread 33

sleep

public static void sleep(long millis) throws InterruptedException public static void sleep(long millis, int nanos) throws InterruptedException il thread che sta eseguendo va in sleep per millis msec e nanos nsec (non perde l'ownership di monitor). ● Le chiamate al metodo sleep() devono essere circondate da un blocco try perchè esso può essere interrotto prima che il tempo specificato sia trascorso.

join

public final void join(long millis) throws InterruptedException Il calling thread va in wait fino alla terminazione del thread callee In caso specifichi nessun argomento o 0 millis il thread aspetterà indefinitamente Appendice 1

Uso di un blocco try

● Le chiamate al metodo sleep() devono essere circondate da un blocco try perchè può essere interrotto prima che il tempo specificato sia trascorso. ● Ciò avviene se qualcuno che ha un riferimento al thread invoca su esso il metodo interrupt() ● il metodo interrupt() ha effetto anche su altri metodi di attesa come wait() e join() che dunque devono essere circondate da un blocco try. ● Tipicamente, se si pianifica di interrompere un thread con interrupt() e di riattivarlo viene utilizzato il metodo wait() note

thread 37

i modelli multithread

cooperativi

  • un thread deve volontariamente rilasciare il controllo della CPU a favore di un altro thread del processo
  • il context switch è veloce ma la programmazione è spesso complicata e non può sfruttare processori multipli ● preemptive
  • il cotrollo è sottratto al thread in tempi casuali
  • contex switch più lenti, ma il multithreading è più facile da programmare e puo eseguire in multiprocessing ● ibrido (POSIX, Solaris..)
  • supporta allo stesso tempo i modelli cooperativo e preemptive

non fare assunzioni sull'ambiente!

si assume che possano valere entrambe le regole: ● Può succerede che un thread impedisca a un altro thread di eseguire fino a quando non rilascia volontariamente l'esecuzione ● Es. chiamando esplicitamente yield(), eseguendo I/O… ● un thread può essere prelazionato in ogni momento da un altro thread, anche da uno che sembra avere priorità inferiore

il comportamento di un thread è platform dependent

● parallelismo/concorrenza si ottengono attraverso il SO ● SO differenti utilizzano modelli di thread differenti ● il comportamento spesso dipende dalla temporizzazione ● le applicazioni multithread possono essere più lente di quelle monothread, ma meglio organizzate

thread 39

Lifecycle di un thread

un thread viene creato attraverso l’invocazione del suo costruttore

  • il nuovo thread avrà una propria identità ed il SO lo tratterà in base al mapping col reale processo di SO, dunque come ogni altro processo, applicandogli le proprie politiche di scheduling. ● il thread inizia la propria esecuzione del task espresso dal metodo run() quando su di esso viene invocato il metodo start() ● un metodo può mettersi in attesa di una condizione [vedi oltre]
  • il passaggio dallo stato waiting/sleeping allo stato running è regolato dal SO ● il flusso esecutivo di un thread che conclude la propria esecuzione confluisce in quello che lo ha originato
  • il thread è terminted

Life Cycle di un Thread 1/

● il thread nasce nello stato NEW invocando il costruttore,

  • è solo un object in heap, senza system resource allocate per l’esecuzione. ● dallo stato NEW, si può invocare solo il metodo start() altrimenti IllegalThreadStateException. ● il metodo start() alloca le system resources necessarie per eseguire il thread, schedula il thread per il run, e “calls back the run()” quando è schedulato.
  • mette il thread in RUNNABLE state.
  • iI computer single CPU supporta multithreading con time-slice di CPU. ● in RUNNABLE state, il thread può essere running o in attesa del suo turno di CPU time.