2015-12-18 6 views
8

Я пишу программу Java, которая печатает секунды, и каждую пятую секунду она печатает сообщение. Это выборка:Несколько потоков с 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 

Как удалить булев переменную printMsg? Есть ли лучший дизайн ниток, которые позволяют это?

В настоящем время, без printMsg программа будет печатать несколько «привет» во второй программе 1/10 пребывания в 5, 10, 15 и т.д.

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

Помещенный 'счетчика% N = 0' проверка в' printTime' и вызывать только 'notifyAll' когда это 'истина' – MadProgrammer

+0

Не должно быть спать 1000 мс, а не 100 мс. Поскольку вы хотите печатать сообщение каждые 5 секунд 'sleep (1000)'; вместо 'sleep (100)'; С помощью этого кода он печатает сообщение каждые 500 мс .. –

ответ

0

Не нужно использовать printMsg флаг, просто notifyAll когда 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

Один из вариантов, чтобы упростить и лучше дизайн использовать одна нить вместо двух потоков. И пусть одна нить заботится о печати секунд, а также о сообщении. Таким образом, уменьшите один поток и не нужно ждать() и уведомлять. Есть ли причина, по которой вы хотите использовать два потока? Код ниже:

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; 
     } 
    } 
} 
Смежные вопросы