数字时钟与多线程只有睡眠,等待和通知

时间:2013-02-10 15:40:19

标签: multithreading sleep wait notify

请你检查下面的代码,这是没有util.concurrent包的数字时钟,使用sleep,notify,wait的Calendar。代码正确执行请建议任何更好的方法。非常感谢

/**
 * 
 */
package com.nagihome.clock;

/**
 * @author Nagi
 * 
 */
public class ThreadAlarmClock {

    private static Integer hours = 23;
    private static Integer minutes = 59;
    private static Integer seconds = 55;
    private static Integer minSecLastNum = 60;
    private static Integer hour24LastNum = 24;
    private static String COLON = ":";
    private static Boolean isMinUpdatable = false;
    private static Boolean isHourUpdatable = false;
    final static Object lock = new Object();

    public void updateSeconds() throws InterruptedException {

        synchronized (lock) {
            while (true) {
                if (isMinUpdatable || isHourUpdatable) {
                    lock.wait();
                } else {
                    Thread.sleep(1000);
                    seconds++;
                    if (seconds.equals(minSecLastNum)) {
                        seconds = 0;
                        isMinUpdatable = true;
                        lock.notifyAll();
                    } else {
                        displayTime();
                    }
                }
            }
        }
    }

    public void updateMinutes() throws InterruptedException {

        synchronized (lock) {
            while (true) {
                if (!isMinUpdatable) {
                    lock.wait();
                } else if (isMinUpdatable) {
                    minutes++;
                    isMinUpdatable = false;
                    if (minutes.equals(minSecLastNum)) {
                        minutes = 0;
                        isHourUpdatable = true;
                    } else {
                        displayTime();
                    }
                }

                lock.notifyAll();
            }
        }
    }

    public void updateHours() throws InterruptedException {

        synchronized (lock) {
            while (true) {
                if (!isHourUpdatable) {
                    lock.wait();
                } else if (isHourUpdatable) {
                    hours++;
                    isHourUpdatable = false;
                    if (hours.equals(hour24LastNum)) {
                        hours = 0;
                    }

                    displayTime();
                }

                lock.notifyAll();
            }
        }
    }

    public void displayTime() {
        System.out.println(hours + COLON + minutes + COLON + seconds);
    }

}


/**
 * 
 */
package com.nagihome.clock;

/**
 * @author Nagi
 * 
 */
public class SecondsThread implements Runnable {

    private ThreadAlarmClock clock;

    public SecondsThread(ThreadAlarmClock clock) {
        this.clock = clock;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            clock.updateSeconds();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 
 */
package com.nagihome.clock;

/**
 * @author Nagi
 * 
 */
public class MinutesThread implements Runnable {

    private ThreadAlarmClock clock;

    public MinutesThread(ThreadAlarmClock clock) {
        this.clock = clock;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            clock.updateMinutes();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 
 */
package com.nagihome.clock;

/**
 * @author Nagi
 * 
 */
public class HoursThread implements Runnable {

    private ThreadAlarmClock clock;

    public HoursThread(ThreadAlarmClock clock) {
        this.clock = clock;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            clock.updateHours();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


/**
 * 
 */
package com.nagihome.main;

import com.nagihome.clock.HoursThread;
import com.nagihome.clock.MinutesThread;
import com.nagihome.clock.SecondsThread;
import com.nagihome.clock.ThreadAlarmClock;

/**
 * @author Nagi
 * 
 */
public class Main {

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        ThreadAlarmClock clock = new ThreadAlarmClock();

        new Thread(new SecondsThread(clock)).start();
        new Thread(new MinutesThread(clock)).start();
        new Thread(new HoursThread(clock)).start();         
    }

}

1 个答案:

答案 0 :(得分:0)

建议:

  • 使用内部毫秒来计算,而不是使用sec ++
  • 睡眠(1000)不能完全睡眠1000毫安,它可以是990'或1110.所以醒来后检查系统时间(或nanoTime),并计算最后一次唤醒时间的差异。例如,如果你发现你已经睡了1010毫安,那么下次你只睡990毫安。