Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java Quiz #41 : time attack !

(FR)
La cellule d'expertise de votre entreprise a développé un Timer pour que vous puissiez mesurer les performances de votre application, mais... ils ont juste oublié de fournir une méthode pour récupérer la valeur du compteur ! Comment faire pour l'afficher une fois la mesure prise ?
Vous ne pouvez intervenir que sur la classe Quiz41, et il est interdit de modifier le code existant ou d'utiliser la Réflexion.
Bonne chance !

(EN)
The Architects Team developed a Timer class to help you measure the performance of your code, but... they forgot to provide a method to get the timer's value ! How can you get it back and print it in the console ?
You can only alter the Quiz41 class ; modifying the already existing code or using Reflection is forbidden.
Good luck !

  1. public class Quiz41 {
  2.  
  3. public static void main(String[] args) throws InterruptedException {
  4.  
  5. Timer timer = new Timer();
  6. timer.start();
  7. Thread.sleep(new Random().nextInt(2000));
  8. timer.stop();
  9.  
  10. }
  11. }
  1. public class Timer {
  2.  
  3. private TimerThread thread = new TimerThread();
  4.  
  5. public void start() {
  6. thread.start();
  7. }
  8.  
  9. public void stop() {
  10. thread.stop();
  11. }
  12.  
  13. public static class TimerThread extends Thread {
  14. private AtomicInteger counter = new AtomicInteger(0);
  15.  
  16. @Override
  17. public void run() {
  18. try {
  19. while (!isInterrupted()) {
  20. counter.incrementAndGet();
  21. Thread.sleep(100);
  22. }
  23. } catch (InterruptedException e) {
  24. interrupt();
  25. }
  26. }
  27.  
  28. public int getCounter() {
  29. return counter.get();
  30. }
  31. }
  32. }

Réponse / Answer :
Soon !


Commentaires

1. Le mardi 24 août 2010, 15:32 par Vincent

Solution rapide :
On récupère les threads (y compris les threads 'fils') dans un tableau.
Le deuxième élément est le TimerThread que l'on cast et on récupère le counter !
Et voilà !

timer.stop();
Thread threads = new Thread[2];
Thread.enumerate(threads);
Thread thread = threads[1];
System.out.println(((Timer.TimerThread) thread).getCounter());

2. Le mardi 24 août 2010, 15:34 par Benoît Dissert

Je propose (on est bien d'accord que je n'écrirai jamais du code comme ça en production :-) ) :

public static void main(String args) throws InterruptedException {



Timer timer = new Timer();
timer.start();

// My code : begin
Set<Thread> allThreads = Thread.getAllStackTraces().keySet();
TimerThread timerThread = null;
for (Thread thread : allThreads) {
if (thread instanceof TimerThread) {
timerThread = (TimerThread)thread;
break;
}
}
// My Code : end


Thread.sleep(new Random().nextInt(2000));
timer.stop();

if ( timerThread == null ) {
System.exit(0);
}
System.out.println("counter = " + timerThread.getCounter());
}

3. Le mardi 24 août 2010, 16:11 par Kevin L'Huillier

public class Quiz41 {

   public static void main(String[] args) throws InterruptedException {
       EH eh = new EH();
       Thread.setDefaultUncaughtExceptionHandler(eh);
       Timer timer = new Timer();
       timer.start();
       Thread.sleep(new Random().nextInt(2000));
       timer.stop();
       Thread.sleep(1000);
       System.out.println(eh.getCounter());
   }
   
   static class EH implements UncaughtExceptionHandler {
       volatile int counter;
       
       @Override
       public void uncaughtException(Thread t, Throwable e) {
           TimerThread tt = (TimerThread) t;
           counter = tt.getCounter();
       }
       
       public int getCounter() {
           return counter;
       }
   }

}

4. Le mardi 24 août 2010, 18:05 par arn

public static void main(String args) throws InterruptedException {

       
       executeInNewGroup(new Runnable() {
           
           @Override
           public void run() {
               
               try {
                   
                   Timer timer = new Timer();
                   timer.start();
                   
                   Thread[] tmpThreads = new Thread[2];
                   Thread.currentThread().getThreadGroup().enumerate(tmpThreads);
                   Timer.TimerThread timerThread = (Timer.TimerThread) tmpThreads[1];
                   
                   Thread.sleep(new Random().nextInt(2000));
                   timer.stop();
  
                   System.out.println(timerThread.getCounter());
               }
               catch (Exception ex) {
                   
                   ex.printStackTrace();
               }
           }
       });
   }
   
   public static void executeInNewGroup(Runnable runnable) throws InterruptedException {
       
       final ThreadGroup group = new ThreadGroup("mygroup");
       Thread thread = new Thread(group, runnable);
       thread.start();
       thread.join();
   }
5. Le mercredi 25 août 2010, 12:57 par Piwaï

Comme d'habitude, j'ai du mal à trouver la solution, mais les commentaires sont tous plus intéressants les uns que les autres :-) Quelle ingéniosité et quelle connaissance des API !

Merci Olivier pour ces énigmes :-)

6. Le jeudi 26 août 2010, 23:37 par Stephen

Since the nested class is both public and static

public class Quiz41 {



public static void main(String args) throws InterruptedException {



TimerThread timer = new TimerThread();
timer.start();
Thread.sleep(new Random().nextInt(2000));
timer.stop();
System.out.println(timer.getCount())



}
}

7. Le lundi 30 août 2010, 16:34 par Ptitourson

Par classe anonyme, je modifie le comportement de la méthode stop() en utilisant un autre objet TimerThread, n'ayant pas accès à l'original déclaré private, non visible dans l'héritage :

Timer timer = new Timer() {
private TimerThread thread2 = new TimerThread();
@Override
public void start() { thread2.start(); }
@Override
public void stop() { thread2.stop(); System.out.println("Counter: " + thread2.getCounter()); }
};

timer.start();
Thread.sleep(new Random().nextInt(2000));
timer.stop();

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.