Eviter auto-blockage

Java runtime system permet à la thread d'utiliser un moniteur déjà obtenu (les moniteurs sont  re-entrant). Comme ca on peut éviter autoblocage

 

public class Reentrant {
public static void main(String a[]){
Reentrant r = new Reentrant();
r.a();
}
public synchronized void a() {
b();
System.out.println("here I am, in a()");
}
public synchronized void b() {
System.out.println("here I am, in b()");
}
}
here I am, in b()
here I am, in a()

 

Timers

Classe

java.util.Timer



Constructor Summary
Timer()
          Creates a new timer.
Timer(boolean isDaemon)
          Creates a new timer whose associated thread may be specified to run as a daemon.
Timer(String name)
          Creates a new timer whose associated thread has the specified name.
Timer(String name, boolean isDaemon)
          Creates a new timer whose associated thread has the specified name, and may be specified to run as a daemon.
Method Summary
 void cancel()
          Terminates this timer, discarding any currently scheduled tasks.
 int purge()
          Removes all cancelled tasks from this timer's task queue.
 void schedule(TimerTask task, Date time)
          Schedules the specified task for execution at the specified time.
 void schedule(TimerTask task, Date firstTime, long period)
          Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
 void schedule(TimerTask task, long delay)
          Schedules the specified task for execution after the specified delay.
 void schedule(TimerTask task, long delay, long period)
          Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
 void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
          Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
 void scheduleAtFixedRate(TimerTask task, long delay, long period)
          Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.



java.util.TimerTask



Constructor Summary
protected TimerTask()
          Creates a new timer task.

Method Summary
 boolean cancel()
          Cancels this timer task.
abstract  void run()
          The action to be performed by this timer task.
 long scheduledExecutionTime()
          Returns the scheduled execution time of the most recent actual execution of this task.


3.8.1. Exemple - une seule fois

import java.util.Timer;
import java.util.TimerTask;


public class TimerReminder {
    Timer timer;
    public TimerReminder(int seconds) {
        timer = new Timer();
        timer.schedule(new RemindTask(), seconds*1000);
    }
    class RemindTask extends TimerTask {
        public void run() {
            System.out.println("Time's up!");
            timer.cancel(); //Terminate the timer thread
        }
    }
    public static void main(String args[]) {
        System.out.format("About to schedule task.%n");
        new TimerReminder(4);
        System.out.println("Task scheduled.");
    }
}
About to schedule task.
Task scheduled.
Time's up!


3.8.2 Exemple - boucle 3 fois

import java.util.Timer;
import java.util.TimerTask;

/**
 * Schedule a task that executes once every second.
 */

public class Beep {
    Timer timer;
  
    public Beep() {
        timer = new Timer();
        timer.schedule(new RemindTask(),
                0,        //initial delay
                1*1000);  //subsequent rate
    } 
    class RemindTask extends TimerTask {
        int numWarningBeeps = 3;
      
        public void run() {
            if (numWarningBeeps > 0) {
                System.out.println("Beep!");
                numWarningBeeps--;
            } else {
                System.out.println("Time's up!");
                timer.cancel();
            }
        }
    }
    public static void main(String args[]) {
        System.out.println("About to schedule task.");
        new Beep();
        System.out.println("Task scheduled.");
    }
}
About to schedule task.
Task scheduled.
Beep!
Beep!
Beep!
Time's up!


Exercises

3.8.3 Un jeu: Si le clique est sur le carré bleu le compteur augmente, si en dehors - le compteur diminue


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JPanel{
    boolean bleu = true;
    public int x=30,y=30, rd=30;
    Label l = new Label("0");
    int cnt=0;
    Color c;
    public void init(){
        c=Color.blue;
        setForeground(c);
        addMouseListener(new MouseHandler());
        add(l);
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g) ;
        g.fillRect(x, y, rd, rd);
    }
    boolean in (int mx,int my){
        if((mx>x) && (mx<x+rd ))
            if((my>y)&&(my<y+rd)) return true;
        return false;
    }
    class MouseHandler extends MouseAdapter {
        public void mousePressed(MouseEvent e){
             if(in(e.getX(),e.getY())) cnt++;
             else cnt--;
             l.setText(cnt+"");
        }
    }
}
//========================
import javax.swing.JFrame;
public class TestApp {
     public static void main(String arg[]) {
            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Test ex = new Test();
            frame.add(ex);
            ex.init();
            frame.setSize(250, 250);
            frame.setVisible(true);
        }
}

3.8.4 Ajouter um timer qui deplace le carré a une position aléatoire une fois par seconde

import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
public class Game {
    static Timer move;
    static Test ex;
    static int width=250, height=250;
    public static void main (String arg[]) {
        move =new Timer();
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ex = new Test();
        frame.add(ex);
        ex.init();
        frame.setSize(width, height);
        frame.setVisible(true);                        
       
        move.schedule(new MvTask(),
                1000,        //initial delay
                1*1000);  //subsequent rate
    }
    static class MvTask extends TimerTask{
        public void run() {
            ex.x= (int)(Math.random()*(ex.getWidth()-ex.rd));
            ex.y= (int)(Math.random()*(ex.getHeight()-ex.rd));
            ex.repaint();                    
        }     
    }
}


3.8.5 Créer une nouvelle classe - Game2 avec 2 timers:

        1) pour deplacer le carré a une position aléatoire une fois par seconde;
          2) pour qu'après un click sur le carré, il change sa couleur en rouge pour 0.2 secondes.