2015-12-18 16 views
8

Piszę program java, który wydrukuje sekundy, a co 5 sekund wyświetli komunikat. To jest przykładowe wyjście:Wiele wątków z notifyAll()

0 1 2 3 4 hello 5 6 7 8 9 hello 10 11 12 13 14 hello 15 16 17 18 19 hello 

Jak mogę usunąć zmienną binarną printMsg? Czy istnieje lepszy projekt gwintów, który na to pozwala?

Na razie bez printMsg program będzie wydrukować wiele „cześć” w ciągu 1/10 sekundy programu pobytu na 5, 10, 15 itd.

class Timer { 
    private int count = 0; 
    private int N; 
    private String msg; 
    private boolean printMsg = false; 

    public Timer(String s, int N) { 
     msg = s; 
     this.N = N; 
    } 

    public synchronized void printMsg() throws InterruptedException{ 
     while (count % N != 0 || !printMsg) 
      wait(); 
     System.out.print(msg + " "); 
     printMsg = false; 
    } 

    public synchronized void printTime() { 
     printMsg = true; 
     System.out.print(count + " "); 
     count ++; 
     notifyAll(); 
    } 

    public static void main(String[] args) { 
     Timer t = new Timer("hello", 5); 
     new TimerThread(t).start(); 
     new MsgThread(t).start(); 
    } 
} 

class TimerThread extends Thread { 
    private Timer t; 
    public TimerThread(Timer s) {t = s;} 

    public void run() { 
     try { 
      for(;;) { 
       t.printTime(); 
       sleep(100); 
      } 
     } catch (InterruptedException e) { 
      return; 
     } 
    } 
} 

class MsgThread extends Thread { 
    private Timer t; 
    public MsgThread(Timer s) {t = s;} 

    public void run() { 
     try { 
      for(;;) { 
       t.printMsg(); 
      } 
     } catch (InterruptedException e) { 
      return; 
     } 
    } 
} 
+0

Umieść 'count% N = 0' zameldowanie' printTime' i tylko zadzwonić 'notifyAll' kiedy to jest "prawda" – MadProgrammer

+0

Nie powinien spać 1000 ms zamiast 100 ms. Ponieważ chcesz drukować wiadomości co 5 sekund 'snu (1000)'; zamiast "uśpienia (100)"; Za pomocą tego kodu drukowany jest komunikat co 500 ms. –

Odpowiedz

0

Nie trzeba używać printMsg flagę, tylko notifyAll gdy count % N == 0

public synchronized void printMsg() throws InterruptedException { 
    wait(); 
    System.out.print(msg + " ");   
} 

public synchronized void printTime() {  
    System.out.print(count + " "); 
    count++; 
    if (count % N == 0){ 
     notifyAll();  
    }    
} 
0

Jedną z opcji w celu uproszczenia i lepiej konstrukcja jest użycie pojedynczy wątek zamiast dwóch wątków. I niech pojedynczy wątek zajmie się drukowaniem sekund, a także wiadomości. W ten sposób można zredukować jeden wątek i nie trzeba czekać() i powiadamiać. Czy jest jakiś powód, dla którego chcesz użyć dwóch wątków? Kod poniżej:

public class Timer { 
    private int count = 0; 
    private int N; 
    private String msg; 

    public Timer(String s, int N) { 
     msg = s; 
     this.N = N; 
    } 

    public synchronized void printTime() { 
     System.out.print(count + " "); 
     count ++; 
     if(count % N == 0) { 
      System.out.print(msg + " "); 
     } 
    } 

    public static void main(String[] args) { 
     Timer t = new Timer("hello", 5); 
     new TimerThread(t).start(); 
    } 
} 

class TimerThread extends Thread { 
    private Timer t; 
    public TimerThread(Timer s) {t = s;} 

    public void run() { 
     try { 
      for(;;) { 
       t.printTime(); 
       sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      return; 
     } 
    } 
} 
Powiązane problemy