Programmation concurrente de 2 threads Java :
sinus || cosinus = ?
class Ball
{
final static boolean SINE = true, COSINE = false;
double x, y, angleX = 0, angleY = 0;
int radius = 8, steps = 100, scale = 5;
public Ball(int x,int y){ this.x = x; this.y = y; }
public void paint(Graphics g,Color color){
g.setColor(color);
g.fillOval((int)x-radius,(int)y-radius,radius*2,radius*2);
g.setColor(Color.black);
g.fillOval((int)x,(int)y,2,2);
}
public void
sine(){
angleY += (2*Math.PI/steps);
y += scale*Math.sin(angleY);
}
public void cosine(){
angleX += (2*Math.PI/steps);
x += scale*Math.sin(angleX+Math.PI/2);
}
}
Le thread de mouvement en sinus ou en cosinus :
class Move extends Thread
{
Ball ball;
Applet applet;
boolean move;
public Move(Ball b,Applet a,boolean m){ ball = b; applet = a; move = m; }
public void run(){
for(;;){
if (move == Ball.SINE) ball.sine(); else ball.cosine();
applet.paint(applet.getGraphics());
}
}
}
L'applet :
public class SinCos extends DoubleBufferedApplet
{
Ball ball = new Ball(startx,starty);
public void paint(Graphics g) { super.paint(g); ball.paint(g,Color.red); }
void circle(Ball ball){
new Move(ball,this,Ball.SINE).start();
new Move(ball,this,Ball.COSINE).start();
}
public void init(){ circle(ball); }
}
Utilisation de yield
public void run(){
for(;;){
if (move == Ball.SINE) ball.sine(); else ball.cosine();
applet.paint(applet.getGraphics());
Thread.yield();
}
}
(marche en coopératif...)
Utilisation de sleep
public void run(){
for(;;){
if (move == Ball.SINE) ball.sine(); else ball.cosine();
applet.paint(applet.getGraphics());
try{Thread.sleep(5);}catch(Exception e){System.out.println(e);}
}
}
pas portable
La solution
public void run(){
for(;;){
synchronized(ball){
if (move == Ball.SINE) ball.sine(); else ball.cosine();
applet.paint(applet.getGraphics());
ball.notify();
try{ball.wait();}catch(Exception e){System.out.println(e);}
}
}
}
résultat
Plusieurs balles...
void circle(Ball ball){
new Move(ball,this,Ball.SINE).start();
new Move(ball,this,Ball.COSINE).start();
}
public void init(){
circle(ball1);
circle(ball2);
circle(ball3);
}
résultat
Les balles ne tournent pas à la même vitesse...
Et que se passe-t-il lorsque il y a plusieurs actions Move ?
public void init(){
circle(ball);
new Move(ball,this,Ball.COSINE).start();
}
résultat
Problème : comment obtenir ce résultat ?
et celui-ci : résultat ?