Académique Documents
Professionnel Documents
Culture Documents
Java threads. Scott Oaks & Henry Wong. Ed. O'Reilly, QA 76.73
.J38 O25 1997.
import java.applet.Applet;
public class OurApplet extends Applet
{
public void init()
{
OurClass oc = new OurClass();
oc.run();
}
}
Ejecucin run()
Applet ejecuta run()
Applet ejecuta init()
Applet antes de init()
Tiempo
import java.applet.Applet;
public class OurApplet extends Applet
{
public void init()
{
OurClass oc = new OurClass();
oc.start();
}
}
Ejecucin run()
Thread ejecuta run()
!
!
!
!
Interface Runnable
!
import java.applet.Applet;
public class OurApplet extends Applet
{
public void init()
{
Runnable ot = new OurClass();
Thread th = new Thread(ot);
th.start();
}
}
!
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
public class HolaMundoSwirl extends
java.applet.Applet implements Runnable{
Font f = new Font("TimesRoman",Font.BOLD,48);
Color colors[] = new Color[50];
Thread runThread;
public void start(){
if(runThread == null){
runThread = new Thread(this);
runThread.start();
}
}
public void stop(){
if(runThread != null){
runThread.stop();
runThread = null;
}
}
public void run(){
float c =0;
for (int i=0;i<color.length;i++){
colors[i] = Color.getHSBColor(c,
(float)1.0,(float)1.0),(float)1.0);
c+=0.02;
}
int i = 0;
while (true){
setForeground(colors[i];
repaint(); // redibuja el rea
i++;
try{
Thread.currentThread().sleep(50);}
catch (InterruptedException e){ }
if (i == (colors.length)) i = 0;
}
}
public void paint(Graphics g){
g.setFont(f);
g.drawString("Hola Mundo!!!",15,50);
}
}
!
Lectura Asncrona
!
Lectura de Sockets.
import java.io.*;
import java.net.*;
public class AsyncReadSocket extends Thread
{
private Socket s;
private StringBuffer result;
public AsyncReadSocket( Socket s)
{
this.s = s;
result = new StringBuffer();
}
public void run()
{
DataInputStream is = null;
try
{
is = new
DataInputStream(s.getInputStream());
} catch (Exception e) {}
while (true)
{
try
{
char c=is.readChar();
result.append;
} catch (Exception e) {}
}
}
Thread Bloqueado
Applet llama a
getResult()
Applet ejecutando
otras tareas
Tiempo
1.
2.
3.
4.
5.
Secuencia de eventos:
El applet entra en getResult()
Es asignado a retval el valor del StringBuffer.
El Thread del socket finaliza la ejecucin de readChar
El Thread del socket aade el char ledo al StringBuffer.
El applet asigna a result un StringBuffer vaco (con new).
Estados de un Thread
Periodo durante start()
Running
Not Running
Ejemplo:
Public class
Runnable{
Thread t;
....
java1005
extends
Applet
implements
Ejemplo de joint()
public class MyApplet extends Applet
{
Thread t;
Public void start()
{
t = new TimerThread(this,500);
t.start();
}
public void stop()
{
t.stop();
try
{
t.join();
} catch (InterrumptedException e){}
}
+"is"
}
}
Una tarea se puede morir de dos formas: por causas naturales
(finaliza la accin del mtodo run()), o matndola.
Ejemplo.
Ejemplo de setName()
import java.awt.*;
public class TimerThread extends Thread{
Component comp; // componente a repintar
int timediff;
// tiempo entre repintado
public TimerThread(Component comp,int timediff){
this.comp=comp;
this.timediff=timediff;
setName("TimerThread("
+
timediff
+
"milliseconds)");
}
public void run(){
while (true){
try{
comp.repaint();
sleep(timediff);
}catch(Exception e){}
}
}
}
! En esta versin de la claseTimerThread, asignamos un nombre
al thread en el constructor.
!
3. Sincronizacin.
!
1)
2)
3)
4)
5)
6)
palabra
clave
}
public synchronized void freeBusyFlag()
{
if(getBusyFlagOwner()==Thread.currentThread())
{
busyflag = null;
}
}
!
public
final
void
wait()
throws
InterruptedException: Si el timeout es cero el thread
esperar a la notificacin.
Ejemplo:
import java.util.*;
import java.io.*;
public class Consumer extends Thread{
protected Vector objects; // array de objetos
public Consumer(){
objects = new Vector();
}
public void run(){
while (true){
Object object = extract();//saca objeto
System.out.println(object);
}
}
protected Object extract(){
synchronized (objects){ //bloqueamos array
while (objects.isEmpty()){
try{
objects.wait();
}catch (InterruptedException ex){
ex.printStackTrace();
}
Object o =objects.firstElement();
objects.removeElement (o);
return o;
}
}
public void insert (Object o){
synchronized(objects){
objects.addElement (o);
objects.notify();
}
}
Gestin de threads
!
Con las tareas en las que se fije MAX_PRIORITY, hay que tener
cuidado, ya que si no se hacen llamadas sleep() o yield(),
se puede provocar que el intrprete Java quede fuera de control.
En T2
o PRIORITY 5: main() -> calcThread ->NULL
o PRIORITY 6: NULL
o BLOCKED:NULL
En T3 comienza reader
o PRIORITY 5: calcThread->main() ->NULL
o PRIORITY 6: reader->NULL
o BLOCKED:NULL
En T4 reader se bloque en espera de datos. Y el primero ahora
es calcThread y se ejecuta.
o PRIORITY 5: main() -> calcThread ->NULL
o PRIORITY 6: NULL
o BLOCKED: reader->NULL
Hasta aqu, el proceso es determinista, pero pueden ocurrir
complicaciones que afecten al gestor de threads de igual
prioridad. Veamos algunos casos:
a. Cuando el thread en ejecucin salga del estado
runnable, bien bloquendose o saliendo. En nuestro
ejemplo esto ocurre cada vez que se bloquea reader.
b. Cuando un thread que tiene una prioridad ms alta que
el thread en ejecucin entra en estado runnable. En
nuestro ejemplo esto ocurre cuando reader entra en
accin o se desbloquea.
c. Cuando se produce una expiracin en un tiempo
arbitrario, Ej: se fija intervalos fijos de 10 veces por
segundo donde hay slo dos threads con prioridad 5:
! PRIORITY 5: main() -> calcThread ->NULL
! PRIORITY 6: NULL
! BLOCKED: reader->NULL
calcThread es el thread en ejecucin. Entonces,
cuando uno de esos intervalos de tiempo cumple se
producen el cambio.
! PRIORITY 5: calcThread->main() ->NULL
! PRIORITY 6: NULL
! BLOCKED: reader->NULL
As, sucesivamente cada decima de segundo.
Thread daemon
!
Ejemplo:
public class SimpleScheduler extends Thread{
int timeslice;
public SimpleScheduler(int t){
timeslice =t;
setPriority(Thread.MAX_PRIORITY);
setDaemon(true);
}
public void run(){
while(true){
try{
sleep(timeslice);
}catch (Exception e){}
}
}
}
Usemos la definicin de esta clase como gestor.
class TestThread extends Thread{
String id;
public TestThread(String s){
id = s;
}
public void run(){
int i;
for(i=0;i<10;i++){
doCalc();
System.out.println(id);
}
}
}
PROBLEMAS:
! Sin embargo, puede suceder que el thread que en ese momento
esta ejecutndose de repente entra en estado de bloqueo.
Supongamos el siguiente estado:
PRIORITY 2: t3->t1->NULL
PRIORITY 4: t2->NULL
BLOQUET: CPUScheduler->NULL
Si t2 se bloquea de repente entonces:
PRIORITY 2: t3->t1->NULL
PRIORITY 4: NULL
BLOQUET: t2->CPUScheduler->NULL
!
class CPUSchedulerNode{
Thread thread;
boolean blocked;
CPUSchedulerNode(Thread t){
thread = t;
blocket = false;
}
public boolean equals(Object o){
if (thread ==o) return true;
return false;
}
}
class ThreadNotifier extends Thread{
CPUScheduler c;
public ThreadNotifier(CPUScheduler c){
setPriority(3);
this.c = c;
}
public void run(){
boolean done=false;
while (!done){
c.wakeup();
}
}
}
threads.getNext();
}
try{
current.Thread.setPriority(4);
}catch(Exception e){
removeThread(current.Thread);
continue;
}
then = now;
if(nBloqued==nThreads)
notification.suspend();
else notification.resume();
try{
wait(timeslice);
}catch (InterruptedException ie){}
now =System.currentTimeMillis();
if(currect !=null) {
try{
current.Thread.setPriority(2);
if (now-then <timeslice){
//thread bloqueado
if(!current.blocked){
current.blocked=true;
nBlocked++; // contaje de
bloqueos.
}
}
else{
if(current.blocked){
current.blocked=false;
nBlocked--; // contaje de
bloqueos.
}
}
}catch(Exception e){
removeThread(current.thread);
}
}
}
}
}