Concorr^encia
I
Concorr^encia em Java
IMultiThreading
Isincronizac~ao
Iinterface Runnable
Igrupos de threads
Iexemplos
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
A classe Thread
(java.lang)
Os threads s~ao dependentes da plataforma. Correm por quantum de tempo em
Windows e em modo preemptive no Solaris.
Escalonador privilegia as prioridades (entre 0 e 10) mais elevadas. Podem
correr em modo daemon.
I
construtores: Thread(String nome), Thread(Runnable obj), ...
I
metodo run() onde existe o codigo do thread
I
metodo start() inicia o thread e termina
I
static sleep(long MiliSegundos) coloca o thread no estado sleep
I
metodo interrupt()
I
metodos suspend() / resume()
I
metodo stop() termina um thread (n~ao e muito usado)
Estados de um thread
I
ready | pronto a executar quando houver 1 CPU
I
running | em execuc~ao
I
suspended | activavel com chamada a resume()
I
blocked | a espera de uma operac~ao E/S
I
sleeping | sem executar por um perodo pre-determinado
I
waiting
I
dead | terminou a sua execuc~ao
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Threads
do livro \Java How to Program", Deitel & Deitel
Threads
{ exemplo simples {
class PrintThread extends Thread f
int sleepTime;
public PrintThread() f
// sleep between 0 and 5 secondssleepTime = (int) ( Math.random() * 5000 );
System.out.println( "Name: " + getName() +
"; sleep: " + sleepTime );
g
public void run() f
try f
Thread.sleep( sleepTime );
// put thread to sleep for a random intervalSystem.out.println(\Dormi durante \+sleepTime+" segundos. Ate ja.");
g
catch (InterruptedException exception) f
System.err.println(exception.toString());
g
System.out.println(getName());
g
g
exemplo do livro \Java How to Program", Deitel & Deitel
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Threads
{ exemplo simples {
public class PrintTest f
// Show multiple threads printing at dierent intervals.public static void main(String args[])f
PrintThread thread1, thread2, thread3, thread4;
thread1 = new PrintThread();
thread2 = new PrintThread();
thread3 = new PrintThread();
thread4 = new PrintThread();
thread1.start();
thread2.start();
thread3.start();
thread4.start();
g
g
exemplo do livro \Java How to Program", Deitel & Deitel
Sincronizac~ao
I
Uso de monitors (C.A. Hoare)
I
Cada objecto com um metodo synchronized e um monitor
I
O monitor deixa um so thread de cada vez correr um metodo
synchronized no objecto
I
todos os threads que tentam invocar um metodo synchronized
num objecto locked t^em que esperar
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Sincronizac~ao
(cont.)
I
quando um metodo synchronized termina o monitor levanta o lock
e o thread ready com maior prioridade pode invocar o metodo
synchronized que pretende
I
metodo synchronized que v^e que n~ao pode executar chama wait e
espera numa la
I
outro metodo pode reactivar o metodo auto-suspendido
noticando-o (notify) que pode voltar a correr
Threads (produtor/consumidor),
sem sincronizac~ao
public class SharedCell f
public static void main(String args[])f HoldInteger h = new HoldInteger();
ProduceInteger p = new ProduceInteger(h); ConsumeInteger c = new ConsumeInteger(h); p.start();
c.start(); g
g
class ProduceInteger extends Threadf private HoldInteger pHold;
public ProduceInteger(HoldInteger h)f pHold = h;
g
public void run()f
for(int count = 0; count < 10; count++)f pHold.setSharedInt(count);
System.out.println("Producer set sharedInt: "+ count); try f Thread.sleep((int) (Math.random() * 3000)); g catch(InterruptedException e) f System.err.println(e.toString()); g g pHold.setMoreData(false); g g
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Threads (produtor/consumidor)
(cont.)sem sincronizac~ao
class ConsumeInteger extends Thread f private HoldInteger cHold;
public ConsumeInteger(HoldInteger h)f cHold = h;
g
public void run()f int val;
while(cHold.hasMoreData())f
tryf Thread.sleep((int) (Math.random() * 3000));g catch(InterruptedException e)f
System.err.println(e.toString()); g
val = cHold.getSharedInt();
System.out.println( "Consumer retrieved " + val ); g
g g
class HoldIntegerf private int sharedInt = -1; private boolean moreData = true;
public void setSharedInt(int val)f sharedInt = val;
g
public int getSharedInt()f return sharedInt; g
public void setMoreData(boolean b)f moreData = b;
g
public boolean hasMoreData()f return moreData;
g g
do livro \Java How to Program", Deitel & Deitel
Resultado
# java SharedCell
Producer set sharedInt to 0
Producer set sharedInt to 1
Consumer retrieved 1
Producer set sharedInt to 2
Consumer retrieved 2
Producer set sharedInt to 3
Producer set sharedInt to 4
Consumer retrieved 4
Consumer retrieved 4
Producer set sharedInt to 5
Producer set sharedInt to 6
Consumer retrieved 6
Producer set sharedInt to 7
Consumer retrieved 7
Producer set sharedInt to 8
Consumer retrieved 8
Consumer retrieved 8
Consumer retrieved 8
Producer set sharedInt to 9
Consumer retrieved 9
Consumer retrieved 9
Consumer retrieved 9
Rui CamachoApresentac~ao Complementos de Programac~ao e Algoritmos { LEIC Java { conceitos BasicosJava { topicos especcos
Threads (produtor/consumidor),
com sincronizac~ao
// Do exemplo anterior so HoldInteger e diferente. class HoldInteger f
private int sharedInt = -1; private boolean moreData = true; //monitor's condition variable private boolean writeable = true;
public synchronized void setSharedInt(int val)f while(!writeable)f try f wait(); g catch(InterruptedException e)f System.err.println("Exception: " + e.toString()); g g sharedInt = val; writeable = false; notify(); g
public synchronized int getSharedInt()f while( writeable ) f try f wait(); g catch(InterruptedException e)f System.err.println("Exception: " + e.toString()); g g writeable = true; notify(); return sharedInt; g
public void setMoreData(boolean b)f moreData = b; g public boolean hasMoreData()f return moreData;g g
Resultado
# java SharedCell
Producer set sharedInt to 0
Consumer retrieved 0
Producer set sharedInt to 1
Consumer retrieved 1
Producer set sharedInt to 2
Consumer retrieved 2
Producer set sharedInt to 3
Consumer retrieved 3
Producer set sharedInt to 4
Consumer retrieved 4
Producer set sharedInt to 5
Consumer retrieved 5
Producer set sharedInt to 6
Consumer retrieved 6
Producer set sharedInt to 7
Consumer retrieved 7
Producer set sharedInt to 8
Consumer retrieved 8
Producer set sharedInt to 9
Consumer retrieved 9
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Buer circular
import java.applet.Applet; import java.awt.*;
import java.text.DecimalFormat;
public class SharedCell extends Appletf private TextArea output;
public void init()f
setLayout(new BorderLayout()); output = new TextArea();
add(output, BorderLayout.CENTER); g
public void start()f
HoldInteger h = new HoldInteger(output); ProduceInteger p = new ProduceInteger(h); ConsumeInteger c = new ConsumeInteger(h); p.start();
c.start(); g
g
class ProduceInteger extends Threadf ... igual ao exemplo anterior ... g
class ConsumeInteger extends Threadf ... igual ao exemplo anterior ...
Buer circular
class HoldIntegerf
private int sharedInt[] = f -1, -1, -1, -1, -1 g; private boolean moreData = true;
private boolean writeable = true; private boolean readable = false; private int readLoc = 0, writeLoc = 0; private TextArea output;
public HoldInteger(TextArea out)f output = out;
g
public synchronized void setSharedInt(int val)f while( !writeable) f
try f
output.append(" WAITING TO PRODUCE "+val); wait(); g catch(InterruptedException e)f System.err.println(e.toString()); g g sharedInt[writeLoc] = val; readable = true; output.append("nnProduced " + val + " into cell " + writeLoc);
writeLoc = (writeLoc + 1) % 5;
output.append("ntwrite "+writeLoc+"ntread "+readLoc); printBuer(output, sharedInt); if(writeLoc == readLoc)f writeable = false; output.append("nnBUFFER FULL"); g notify(); g
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Buer circular
public synchronized int getSharedInt()f int val;
while(!readable)f try f
output.append( " WAITING TO CONSUME" ); wait(); g catch ( InterruptedException e ) f System.err.println( e.toString() ); g g writeable = true; val = sharedInt[readLoc]; output.append("nnConsumed " + val + " from cell " + readLoc); readLoc = (readLoc + 1) % 5;
output.append( "ntwrite " + writeLoc + "ntread " + readLoc); printBuer(output, sharedInt); if(readLoc == writeLoc)f readable = false; output.append("nnBUFFER EMPTY"); g notify(); return val; g
Buer circular
public void printBuer( TextArea out, int buf[])f
DecimalFormat threeChs = new DecimalFormat(" #;-#"); output.append("ntbuer: ");
for(int i = 0; i < buf.length; i++)
out.append(" " + threeChs.format(buf[i])); g
public void setMoreData(boolean b)f moreData = b;
g
public boolean hasMoreData()f
if (moreData == false && readLoc == writeLoc) return false;
else return true; g
g
exemplo do livro \Java How to Program", Deitel & Deitel
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Threads Daemon
I
s~ao executados para benefcio de outros threads
I
correm em background
I
tornar um thread em daemon: setDaemon(true)
I
a propriedade daemon tem que ser activada antes do metodo start()
I
se so existirem daemons o Java termina
I
ex: garbage collection
Interface Runnable
I
usar a classe Thread implica heranca dessa classe
I
multithreading sem heranca de Thread ! uso do interface Runnable
I
declarac~ao: class Classe implements Runnable
I
codigo tambem guardado em run()
I
criac~ao: Thread(Runnable object) ou
Thread(Runnable object, String threadName)
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Interface Runnable
{ exemplo {
import java.applet.Applet; import java.awt.*; import java.awt.event.*;
public class RandomCharacters extends Applet implements Runnable, ActionListener f private String alphabet;
private TextField output1, output2, output3; private Button button1, button2, button3; private Thread thread1, thread2, thread3; private boolean suspend1, suspend2, suspend3; public void init()f
alphabet = new String( "ABCD...YZ"); output1 = new TextField(10);
output1.setEditable(false); output2 = new TextField(10); output2.setEditable(false); output3 = new TextField(10); output3.setEditable(false);
button1 = new Button("Suspend/Resume 1"); button1.addActionListener(this);
button2 = new Button("Suspend/Resume 2"); button2.addActionListener(this);
button3 = new Button("Suspend/Resume 3"); button3.addActionListener(this); add(output1); add(button1); add(output2); add(button2); add(output3); add(button3); g
Interface Runnable
{ exemplo
(cont.){
public void start()f
// create threads and start every time start is called
thread1 = new Thread(this, "Thread 1");
thread2 = new Thread(this, "Thread 2");
thread3 = new Thread(this, "Thread 3");
thread1.start();
thread2.start();
thread3.start();
g
public void stop()f
// stop threads every time stop is called
// as the user browses another Web page
thread1.stop();
thread2.stop();
thread3.stop();
g
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos
Interface Runnable
{ exemplo
(cont.){
public void actionPerformed(ActionEvent e)fif(e.getSource() == button1) if(suspend1)f thread1.resume(); suspend1 = false; g else f thread1.suspend(); output1.setText("suspended"); suspend1 = true; g
else if (e.getSource() == button2) if (suspend2) f thread2.resume(); suspend2 = false; g else f thread2.suspend(); output2.setText("suspended"); suspend2 = true; g
else if (e.getSource() == button3) if (suspend3) f thread3.resume(); suspend3 = false; g else f thread3.suspend(); output3.setText("suspended"); suspend3 = true; g g
Interface Runnable
{ exemplo
(cont.){
public void run()fint location; char display;
Thread executingThread; while (true) f
// sleep from 0 to 5 seconds try f Thread.sleep((int) (Math.random() * 3000)); g catch (InterruptedException e) f e.printStackTrace(); g
location = (int) (Math.random() * 26); display = alphabet.charAt(location); executingThread = Thread.currentThread(); if (executingThread == thread1)
output1.setText("Thread 1: " + display); else if (executingThread == thread2)
output2.setText("Thread 2: " + display); else if (executingThread == thread3)
output3.setText("Thread 3: " + display); g
g g
exemplo do livro \Java How to Program", Deitel & Deitel
Rui Camacho Complementos de Programac~ao e Algoritmos { LEIC
Apresentac~ao Java { conceitos Basicos
Java { topicos especcos