java简单实现定时器

版权声明:丑九怪绝对原创 https://blog.csdn.net/meixiling/article/details/88874394

wait与sleep

wait:wait的使用必须基于synchronize(对象)块,wait只是将当前线程放入阻塞队列,也就是进入阻塞态,CPU还是可以去跑其他的线程。
sleep:sleep是占着CPU,这段时间之内,CPU什么也不做,就等着时间结束,也就是说,浪费了很多资源(时间)

计时器的分析

计时器的用法,时间一到,就去执行某段代码,每隔固定时间,执行一次代码,要求时间的精度高,在毫秒级别的误差。并且可以控制开始和结束。

计时器核心实现思想

两个线程:其中第一个线程是我们的计时线程,主要负责wait一段固定的时间和唤醒处于同一锁下的另一个线程,而另一个线程在一开始(初始化之后)就要进入阻塞态等待被唤醒,当第一个线程的wait结束之后,立即唤醒第二个线程,让其进入就绪态,这时,如果CPU去运行第一个线程,这个线程会出现短暂的阻塞(时间就是我们设定的时间),在这段时间里就这两个线程而言,CPU只会去运行第二个线程下的其余代码(也就是每隔一段时间就会运行的代码),当运行完毕之后,也就是在第一个线程的wait结束之前,第二个线程再次进入阻塞态,等第一个线程wait的时间一到,立即被唤醒,然后重复上述过程

上代码

// 这是启动线程的代码
public void startClock() {
  if (goon) {
   return;
  }
  goon = true;
  new DidaWoker();
  new Thread(this, "滴答滴答").start();
 }
 
 // 这是run方法
 @Override
 public void run() {
  while (goon) {
   synchronized(lock) {
    try {
     lock.wait(delayTime);
     lock.notify();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
// 这是第二个线程的类,这里我用一个内部类去实现
class DidaWoker implements Runnable {
  public DidaWoker() {
   new Thread(this).start();
  }
  
  @Override
  public void run() {
   while (goon) {
    synchronized (lock) {
     try {
      lock.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
    // 这个方法是一个抽象方法,由外部决定要做什么
    doSomething();
   }
  }
// 测试的代码
public static void main(String[] args) {
  Didadida dida = new Didadida() {
  // 实现抽象方法
   @Override
   public void doSomething() {
    System.out.println(System.currentTimeMillis());
   }
  };
  dida.setDelayTime(1000);
  dida.startClock();
 }

这是运行结果,可以看出,时间上的误差,我们可以控制在毫秒级别

限制

这个方法,有一定的限制:我们设定的时间,要比运行doSomething()方法的时间稍长一点,这样才能保证比较精确的计时,一旦doSomething()完全运行一遍的时间过长,可能会导致第一个线程重复wait,相当于等待时间大于我们设定的时间而小于两倍我们设定的时间。

猜你喜欢

转载自blog.csdn.net/meixiling/article/details/88874394