viernes, 27 de febrero de 2009
Codigo deFiguras Primitivas en Java con Documentacion
import java.awt.event.*;
// Clase de control del ejemplo
class java1516 extends Frame {
// Función de control de la aplicación
public static void main( String[] args ) {
// Se instancia un objeto de la clase
new java1516();
}
// Contructor de la clase
public java1516() {
this.setTitle( "Tutorial de Java, Gráficos" );
this.setSize( 475,275 );
this.setVisible( true );
// Clase anidada que permite terminar la ejecución de la animación
this.addWindowListener(
// Definición de la clase anónima para controlar el cierre de
// la ventana
new WindowAdapter() {
public void windowClosing( WindowEvent evt ) {
// Se concluye el programa
System.exit( 0 );
}
} );
}
// Se sobrecarga el método paint()
public void paint( Graphics g ){
g.setColor( Color.red );
// Trasladamos el origen de coordenadas que se sitúa en la
// esquina superior izquierda, para evitar el problema que se
// produce con insets. De este modo el origen de coordenadas sí
// que lo dejamos situado en la zona cliente del objeto Frame
// que es la que se utiliza para pintas
g.translate( this.getInsets().left,this.getInsets().top );
// Línea simple
g.drawLine( 10,0,50,50 );
g.setColor( Color.black );
g.drawString( "drawLine",10,62 );
g.setColor( Color.red );
// Se crean dos arrays de coordenadas para pintar una
// polilínea
int x1Datos[] = {80,130,80,130};
int y1Datos[] = {0,50,50,0};
g.drawPolyline( x1Datos,y1Datos,4 );
g.setColor( Color.black );
g.drawString( "drawPolyline",70,62 );
g.setColor( Color.red );
// Rectángulo
g.drawRect( 150,0,50,50 );
g.setColor( Color.black );
g.drawString( "drawRect",150,62 );
g.setColor( Color.red );
// Rectángulo relleno
g.fillRect( 220,0,50,50 );
g.setColor( Color.black );
g.drawString( "fillRect",225,62 );
g.setColor( Color.red );
// Rectángulo redondeado
g.drawRoundRect( 300,0,50,50,10,10 );
g.setColor( Color.black );
g.drawString( "drawRoundRect",280,62 );
g.setColor( Color.red );
// Rectángulo redondeado relleno
g.fillRoundRect( 385,0,50,50,10,10 );
g.setColor( Color.black );
g.drawString( "fillRoundRect",375,62 );
// Pinta un rectángulo 3D, sobresaliendo de la pantalla
// No parece demasiado 3D
g.setColor( Color.gray );//draw the 3D stuff in gray
g.draw3DRect( 10,90,55,25,true );
// Rectángulo 3D, pulsado
g.draw3DRect( 70,90,50,25,false );
g.setColor( Color.black );
g.drawString( "draw3DRect",30,140 );
// Rectángulo 3D relleno. Se ha puesto un fondo gris
// con lo cual se puede apreciar mucho mejor el efecto
// de tres dimensiones
// Fondo gris
g.setColor( Color.gray );
g.fillRect( 145,75,130,55 );
g.fill3DRect( 155,90,50,25,true );
// Rectángulo 3D relleno, pulsado
g.fill3DRect( 215,90,50,25,false );
g.setColor( Color.red );
// De todos modos, la apariencia de tres dimensiones
// con 3DRect no es demasiado buena, porque es necesario
// seleccionar muy bien la paleta de colores para que
// se genere la ilusión de 3D
g.setColor( Color.black );
g.drawString( "fill3DRect",180,140 );
g.setColor( Color.red );
// Pinta un ángulo de 255 grados inscrito en un rectángulo
g.drawRect( 300,77,50,50 );
g.drawArc( 300,77,50,50,0,225 );
g.setColor( Color.black );
g.drawString( "drawArc",305,140 );
g.setColor( Color.red );
// Angulo relleno de 255 grados inscrito en un rectángulo
g.drawRect( 385,77,50,50 );
g.fillArc( 385,77,50,50,0,225 );
g.setColor( Color.black );
g.drawString( "fillArc",395,140 );
g.setColor( Color.red );
// Elipse, con el eje grande horizontal
g.drawOval( 10,165,50,25 );
// Círculo
g.drawOval( 70,150,50,50 );
g.setColor( Color.black );
g.drawString( "drawOval",35,218 );
g.setColor( Color.red );
// Elipse rellena, con el eje grande vertical
g.fillOval( 170,150,25,50 );
// Círculo relleno
g.fillOval( 210,150,50,50 );
g.setColor( Color.black );
g.drawString( "fillOval",185,218 );
g.setColor( Color.red );
// Polígono
int x2Datos[] = {300,350,300,350};
int y2Datos[] = {150,200,200,150};
g.drawPolygon( x2Datos,y2Datos,4 );
g.setColor( Color.black );
g.drawString( "drawPolygon",290,218 );
g.setColor( Color.red );
// Polígono relleno
int x3Datos[] = {385,435,385,435};
int y3Datos[] = {150,200,200,150};
g.fillPolygon( x3Datos,y3Datos,4 );
g.setColor( Color.black );
g.drawString( "fillPolygon",385,218 );
}
}
domingo, 15 de febrero de 2009
Metodos de sincronizacion
Se usan en exclusión mutua y sincronización.
¿Qué aportan?
• Simplicidad en protocolos de sincronización
• No son necesarios bucles de espera
Un semáforo es una variable entera no negativa que puede
actualizarse sólo con dos procedimientos: P y V, o wait y signal.
Wait(S) Si S>0 se decrementa S en 1
Si S<=0 se bloquea hasta que S>0, y al desbloquearse se
decrementa en 1.
Signal(S) ++S
¡Son indivisibles!
Mutex
Cuando dos o más subprocesos tienen que obtener acceso a un recurso compartido al mismo tiempo, el sistema necesita un mecanismo de sincronización para garantizar que sólo uno de los subprocesos utilice el recurso en ese momento. Mutex es un primitivo de sincronización que otorga acceso exclusivo al recurso compartido a un solo subproceso. Cuando un subproceso adquiere una exclusión mutua (mutex), el siguiente subproceso que intenta adquirir dicha exclusión mutua se suspende hasta que el primer subproceso libera la exclusión mutua.
Barrera(Barriers)
Enunciado. Un proceso crea N hilos. El comportamiento de cada uno consiste en la ejecución de un bucle con tres partes:
A
BARRERA
B
En cada iteración del bucle los hilos ejecutarán A sin realizar ninguna sincronización; a continuación todos ellos esperan a que el resto llegue a la BARRERA. Una vez que todos han llegado a la barrera (todos han ejecutado A), continúan ejecutando B y el bucle se repite.
Salidas. Cada hilo deberá informar del número de iteración junto con el punto del bucle que acaba de ejecutar.
Finalización. Ejecutar la iteración un cierto número de veces
Esquema del problema
Muchos problemas de cálculo se pueden resolver de acuerdo al siguiente esquema:
Ejemplos:
–procesamiento de imágenes
–funciones definidas sobre mallas de puntos
–resolución de sistemas de ecuaciones
–problemas de optimización, etc.
La ejecución de “esperar al resto de procesos” es una sincronización, este tipo se denomina “sincronización por barrera”.
http://it.aut.uah.es/danihc/DHC_files/menus_data/SCTR/Sinc_Com_Variables.pdf
http://msdn.microsoft.com/es-es/library/system.threading.mutex(VS.80).aspx
http://www.mitecnologico.com/Main/BarrerasBarrier
Planificacion de Procesos
En la planificación de plazo fijo se programan ciertos trabajos para terminarse en un tiempo específico o plazo fijo. Estas tareas pueden tener un gran valor si se entregan a tiempo, y carecer de él si se entregan después del plazo. Esta planificación es compleja por varios motivos:
El usuario debe informar por adelantado de las necesidades precisas de recursos del proceso. Semejante información rara vez está disponible.
-El sistema debe ejecutar el proceso en un plazo fijo sin degradar demasiado el servicio a los otros usuarios y debe planificar cuidadosamente sus necesidades de recursos dentro del plazo. Esto puede ser difícil por la llegada de nuevos procesos que impongan demandas imprevistas al sistema.
-Si hay muchas tareas a plazo fijo activas al mismo tiempo, la planificación puede ser tan compleja que se necesiten métodos de optimización avanzados para cumplir los plazos.
-La administración intensiva de recursos requerida por la planificación de plazo fijo puede producir un gasto extra substancial.
Planificación Primero en Entrar-Primero en Salir (FIFO, First In First Out)
Cuando se tiene que elegir a qué proceso asignar la CPU se escoge al que llevara más tiempo listo. El proceso se mantiene en la CPU hasta que se bloquea voluntariamente.
La ventaja de este algoritmo es su fácil implementación, sin embargo, no es válido para entornos interactivos ya que un proceso de mucho cálculo de CPU hace aumentar el tiempo de espera de los demás procesos . Para implementar el algoritmo sólo se necesita mantener una cola con los procesos listos ordenada por tiempo de llegada. Cuando un proceso pasa de bloqueado a listo se sitúa el último de la cola.
Planficación por Turno Rotatorio (Round Robin).
Este es uno de los algoritmos más antiguos, sencillos y equitativos en el reparto de la CPU entre los procesos, muy válido para entornos de tiempo compartido. Cada proceso tiene asignado un intervalo de tiempo de ejecución, llamado cuantum o cuanto. Si el proceso agota su cuantum de tiempo, se elige a otro proceso para ocupar la CPU. Si el proceso se bloquea o termina antes de agotar su cuantum también se alterna el uso de la CPU. El round robin es muy fácil de implementar. Todo lo que necesita el planificador es mantener una lista de los procesos listos.
Planificación por Prioridad al más corto (SJF, Short Job First).
Al igual que en el algoritmo FIFO las ráfagas se ejecutan sin interrupción, por tanto, sólo es útil para entornos batch. Su característica es que cuando se activa el planificador, éste elige la ráfaga de menor duración. Es decir, introduce una noción de prioridad entre ráfagas. Hay que recordar que en los entornos batch se pueden hacer estimaciones del tiempo de ejecución de los procesos.
La ventaja que presenta este algoritmo sobre el algoritmo FIFO es que minimiza el tiempo de finalización promedio
Planificación por Prioridad al Tiempo Restante más Corto (SRTF, Short Remaining Time First).
Es similar al anterior, con la diferencia de que si un nuevo proceso pasa a listo se activa el dispatcher para ver si es más corto que lo que queda por ejecutar del proceso en ejecución. Si es así el proceso en ejecución pasa a listo y su tiempo de estimación se decrementa con el tiempo que ha estado ejecutándose.
Planificación a la Tasa de Respuesta más Alta
Brinch Hansen desarrolló la estrategia de prioridad a la tasa de respueta más alta (HRN, highest-response-ratio-next) que corrige algunas deficiencias de SJF, particularmente el retraso excesivo de trabajos largos y el favoritismo excesivo para los trabajos cortos. HRN es un disciplina de planificación no apropiativa en la cual la prioridad de cada proceso no sólo se calcula en función del tiempo de servicio, sino también del tiempo que ha esperado para ser atendido. Cuando un trabajo obtiene el procesador, se ejecuta hasta terminar.
Planificación por el Comportamiento
Con este tipo de planificación se pretende garantizar al usuario cierta prestación del sistema y tratar de cumplirla. Si en un sistema tenemos 'n' usuarios lo normal será garantizar a cada uno de ellos al menos 1/n de la potencia del procesador. Para ello necesitamos del tiempo consumido por el procesador y el tiempo que lleva el proceso en el sistema. La cantidad de procesador que tiene derecho a consumir el proceso será el cociente entre el tiempo que lleva en el sistema entre el número de procesos que hay en el sistema. A esa cantidad se le puede asociar una prioridad que vendrá dada como el cociente entre tiempo de procesador que ha consumido y el tiempo que se le prometió (el tiempo que tiene derecho a consumir). De tal modo que si esa proporción es de 0'5 significa que tan sólo ha consumido la mitad del tiempo prometido pero si es de 2 quiere decir que ha consumido más de lo debido, justamente el doble.
http://wwwdi.ujaen.es/~lina/TemasSO/PLANIFICACIONDEPROCESOS/6AlgoritmosdePlanificacionI.htm
jueves, 12 de febrero de 2009
Operadores de bits
<< Desplazamiento a izquierda
>> Desplazamiento a derecha
& AND; compara dos bits
^ XOR (OR exclusivo); compara dos bits
| OR inclusivo; compara dos bits
El primero es un operador unario, los restantes son binarios. Los tres primeros realizan manipulaciones en los bits del operando. Los restantes realizan comparaciones lógicas entre los bits de ambos operandos, similares a las que realizan los operadores lógicos entre objetos booleanos.
~ Complemento a uno
Este operador unitario invierte cada bit del operando; 0 es convertido en 1 y viceversa.
Ejemplo
int s1 = ~2;
La representación binaria de los los complementos a uno de los decimales 0, 1 y 2 son los que se expresan (para simplificar los representamos como un octeto):
0 == 0000 0000 ~ 0 == 1111 1111
1 == 0000 0001 ~ 1 == 1111 1110
2 == 0000 0010 ~ 2 == 1111 1101
<< Desplazamiento a izquierda
Este operador binario realiza un desplazamiento de bits a la izquierda. El bit más significativo (más a la izquierda) se pierde, y se le asigna un 0 al menos significativo (el de la derecha). El operando derecho indica el número de desplazamientos que se realizarán.
Sintaxis
expr-desplazada << expr-desplazamiento
El patrón de bits de expr-desplazada sufre un desplazamiento izquierda del valor indicado por la expr-desplazamiento. Ambos operandos deben ser números enteros o enumeraciones
Ejemplo
long x = 10;
int y = 2;
long z = x << y;
El resultado del desplazamiento de 2 bits sobre el unsigned long x es asignado al unsigned long y sin que sea necesario ningún "casting" para el tipo resultante.
Según las premisas anteriores, los desplazamientos izquierda de valor unitario aplicados sobre los números 0, 1, 2 y -3, producen los siguientes resultados:
0 == 0000 0000 0 << 1 == 0000 0000 == 0
1 == 0000 0001 1 << 1 == 0000 0010 == 2
2 == 0000 0010 2 << 1 == 0000 0100 == 4
-3 == 1111 1101 -3 << 1 == 1111 1010 == - 6
>> Desplazamiento a derecha
Sintaxis
expr-desplazada >> expr-desplazamiento
Ejemplo:
long x = 10;
long z = x >> 2;
El patrón de bits de expr-desplazada sufre un desplazamiento derecho del valor indicado por la expr-desplazamiento. El bit menos significativo (a la derecha) se pierde, pero hay que advertir que si expr-desplazada es un entero con signo y es negativo, el resultado depende de la implementación.
Por lo demás, el comportamiento de este operador es análogo al anterior (desplazamiento izquierda). Por ejemplo:
0 == 0000 0000 0 >> 1 == 0000 0000 == 0
2 == 0000 0010 2 >> 1 == 0000 0001 == 1
-2 == 1111 1110 -2 >> 1 == 1111 1111 == -1 (C++Builder & GNU-C++)
-16 == 1111 0000 -16 >> 2 == 1111 1100 == -4 (C++Builder & GNU-C++)
& AND lógico
Este operador binario compara ambos operandos bit a bit, y como resultado devuelve un valor construido de tal forma que cada bits es 1 si los bits correspondientes de los operandos están a 1. En caso contrario devuelve 0 (ver ejemplo).
Sintaxis
AND-expresion & equality-expresion
Ejemplo:
int x = 10, y = 20;
int z = x & y;
En este caso el resultado del AND lógico entre los enteros 10 y 20 se aplicaría al entero z.
Según las reglas del enunciado, el operador & aplicado entre los valores 2 y -2 resultaría:
2 == 0000 0010
-2 == 1111 1110
------------------
0000 0010 == 2
^ XOR OR exclusivo
El funcionamiento de este operador binario es parecido al AND lógico , salvo que en este caso el resultado es 1 si ambos bits son complementarios (uno es 0 y el otro 1). En caso contrario devuelve 0.
expr-OR-exclusiva ^ AND-expresion
Ejemplo:
int x = 10, y = 20;
int z = x ^ y;
Según el enunciado, el operador ^ aplicado entre los valores 7 y -2 resultaría:
7 == 0000 0111
-2 == 1111 1110
------------------
1111 1001 == -7
| OR inclusivo
Este operador binario tiene un funcionamiento parecido a los anteriores (AND y XOR), salvo que en este caso el resultado es 1 si alguno de ellos está a 1. En caso contrario devuelve 0 (ver ejemplo).
Sintaxis
expr-OR-inclusiva | expr-OR-exclusiva
Ejemplo:
int x = 10, y = 20;
int z = x | y;
Según el enunciado, el operador | aplicado entre los valores 6 y 13 resultaría:
6 == 0000 0110
13 == 0000 1101
------------------
0000 1111 == 15
Campos de Bits
Nota: esta técnica, de manejo independiente de bits en una palabra, ha sido ampliamente utilizada desde siempre en la programación, no solo de C/C++; casi todos los lenguajes ofrecen la posibilidad de operadores "bitwise", que permiten esto de forma más o menos artesanal.
Manejo de Bits
El manejo de bits es muy útil para diversas tareas, como la codificación de archivos, o en materia de seguridad y consistencia de los datos. El manejo de bits es posible gracias a una serie de operadores muy parecidos a los de la lógica, de los cuales se hará mención más adelante.
Tipos de Datos Enumerables
Class prueba Enum
{
Public enum Dia_d_la_semana
{
Lunes=1;
Martes=2;
Miércoles=3;
Jueves=4;
Viernes=5;
}
Dia_d_la_semana Dias;
Dias=Dias_d_la_semana.Lunes;
Int i;=(int)Dias;
}
En este ejemplo de tipo enum, se relacionan los días de la semana con un número del 1 al 5, después se crea un objeto del tipo enum Dia_d_la_semana, pero no se inicializa sino hasta la siguiente línea, que hace que en lugar de inicializarse con todos los campos de Dia_d_la_semana solo tome el valor de Lunes=1, y al final la variable i tendrá valor 1, ya que el único campo inicializado en el objeto Dias es Lunes, y Lunes tiene un valor entero 1, al hacer el cast a entero, la variable i termina con el valor entero correspondiente a Lunes.
Registros Variantes
En Java y en C#, se utiliza el tipo de dato Object, que al ser inicializado como una instancia de una clase, estructura o unión, toma el valor de ese objeto, el uso de este tipo de dato es muy útil cuando no se sabe qué tipo de objeto se va a capturar, mas sin embargo necesitamos de capturarlo para poder mostrar el valor de sus diversas variables o campos.
mport javax.swing.JOptionPane;
class Cuadrado
{
public int lado;
Cuadrado(int x)
{
lado=x;
}
}
class Triangulo
{
public int base,altura;
Triangulo(int b,int h)
{
base=b;
altura=h;
}
}
class Circulo
{
public int radio;
Circulo(int r)
{
radio=r;
}
}
public class Main
{
public static void main(String[] args)
{
Object resultado=Figura(Integer.parseInt(JOptionPane.showInputDialog("Teclea:\n1. cuadrado/n2. triangulo\n3. ciruclo")));
}
public static Object Figura(int opcion)
{
Object variable=null;
boolean flag=true;
while(flag)
{
switch(opcion)
{
case 1:variable=new Cuadrado(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor del lado del cuadrado")));
flag=false;
break;
case 2:variable=new Triangulo(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor de la base del triangulo")),Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor de la altura del cuadrado")));
flag=false;
break;
case 3:variable=new Circulo(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor del lado del cuadrado")));
flag=false;
break;
default:JOptionPane.showMessageDialog(null,"Ese numero no esta en la lista");
}
}
return variable;
}
}
En este código de Java, se muestra que existe una incertidumbre de qué tipo de figura escogerá el usuario, mas sin embargo, la variable resultado puede capturar cualquier tipo de objeto para así después poder acceder a sus variables.
Uniones de Datos
Como todos los miembros son almacenados en el mismo espacio de memoria, existe el riesgo de la perdida de información, o el cambio de valor indeseado de algunas variables.
Union ejemplo
{
public char chval;
public int intval;
}
ejemplo valores=new ejemplo();
valores.intval=65;
console.writeline(“chval:{0}”,valores.chval);
Al darle valor al entero de 65, como el valor del carácter está en la misma localidad de memoria, a la hora de imprimir el valor del carácter se imprime el carácter correspondiente al numero según el código ASCII que en este caso sería una A.
Agregación de Datos (Struct)
La palabra clave struct es usada para definir una estructura, es una forma versátil de trabajar con fichas de información. Este tipo de dato se suele utilizar en la encapsulación de pequeños grupos de variables relacionadas.
En sí mismo, es muy parecido a una clase en la programación orientada a objetos, solo que los datos struct no almacenan métodos, solo sirven como manera de agrupción.
Una declaración de estructura define un tipo, y así, es posible también definir variables de este nuevo tipo. Por ejemplo:
//
Publid Struct Alumno
{
public String Nombre;
public int Edad;
public char Sexo;
public DateTime Fecha;
};//
Una ves que hemos declarado el tipo de dato Struct, podemos crear variables de este nuevo tipo de dato.
Alumno alumnos;
alumnos.Nombre=Andres;
alumnos.Edad=19;
alumnos.Sexo=’M’;
alumnos.Fecha=new DateTime(13/05/89);
lunes, 2 de febrero de 2009
Programa estructuras con clases en java
import javax.swing.JOptionPane;
class Cuadrado
{
public int lado;
Cuadrado(int x)
{
lado=x;
}
}
class Triangulo
{
public int base,altura;
Triangulo(int b,int h)
{
base=b;
altura=h;
}
}
class Circulo
{
public int radio;
Circulo(int r)
{
radio=r;
}
}
public class Main {
public static void main(String[] args) {
Object resultado=Figura(Integer.parseInt(JOptionPane.showInputDialog("Teclea:\n1. cuadrado/n2. triangulo\n3. ciruclo")));
}
public static Object Figura(int opcion)
{
Object variable;
boolean flag=true;
while(flag)
{
switch(opcion)
{
case 1:variable=new Cuadrado(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor del lado del cuadrado")));
flag=false;
break;
case 2:variable=new Triangulo(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor de la base del triangulo")),Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor de la altura del cuadrado")));
flag=false;
break;
case 3:variable=new Circulo(Integer.parseInt(JOptionPane.showInputDialog("Teclea el valor del lado del cuadrado")));
flag=false;
break;
default:JOptionPane.showMessageDialog(null,"Ese numero no esta en la lista");
}
}
return variable;
}
}