Java 具有notifyAll()的多个线程

Java 具有notifyAll()的多个线程,java,multithreading,Java,Multithreading,我正在编写一个java程序,它在几秒钟后打印一条消息,每隔5秒钟它就会打印一条消息。这是一个示例输出: 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等时打印多个“hello” class Timer { private int count

我正在编写一个java程序,它在几秒钟后打印一条消息,每隔5秒钟它就会打印一条消息。这是一个示例输出:

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等时打印多个“hello”

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;
        }
    }
}

简化和更好设计的一个选择是使用单线程而不是两个线程。让单线程负责打印秒数和消息。这样可以减少一个线程,而不需要等待()和通知。有什么理由要使用两个线程吗?代码如下:

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;
        }
    }
}

不需要使用printMsg标志,只要在
计数%N==0时
notifyAll

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();    
    }               
}

放入
计数%N!=0
签入
printTime
并仅在
为true时调用
notifyAll
,它不应该休眠1000毫秒而不是100毫秒。因为您希望每5秒打印一次消息
休眠(1000)
;而不是
睡眠(100)
;使用此代码,它每500毫秒打印一次消息。。