关于滴答滴答——定时器

前言:
关于定时器,我们日常生活中应用很多,比如空调,烤箱,微波炉或者一些手机软件等等都有定时功能,在我们设定的时间一到,它们就会自动关闭,这样为我们的生活提供了很多方便。在编程中也是同样的道理,在某些应用场合,需要定时地完成一些操作,希望能有一个“精准”定时的工具,方便编程。下面我们就来介绍一个简单的滴答滴答定时器。

思路:应该有一个线程,这个线程每经过一段时间(这个时间可以指定),就会“醒来”,并执行外部要求完成的操作。不管这个操作是否完成,只要时间片段一到,它就再次会去执行这个操作。

接下来我们看一下具体的代码。
SimpleDidaDida类:

public abstract class SimpleDidaDida implements Runnable{
	private static final long DEFULT_DELAY = 1000;//默认时间
	
	public long delay;
	public volatile boolean goon;
	private Object lock;
	
	public SimpleDidaDida() {
		this(DEFULT_DELAY);
	}
	
	public SimpleDidaDida(long delay) {
		this.lock = new Object();
		this.delay = delay;
	}
	
	public void start() {
		if (goon == true) {
			return;
		}
		goon = true;
		new Thread(this).start();
	}
	
	public void stop() {
		if (goon == false) {
			return;
		}
		goon = false;
	}

	public abstract void doSomething();
	
	@Override
	public void run() {
		while (goon) {
			synchronized (lock) {
				try {
					lock.wait(delay);
					new innerWorker();
				} catch (InterruptedException e) {
					goon = false;
				}
			}
		}
	}
	
	private class innerWorker implements Runnable {
		
		public innerWorker() {
			new Thread(this).start();
		}

		@Override
		public void run() {
			doSomething();
		}
		
	}

}

从上面代码可以看出,我们开启一个线程专门去定时,再另外开启一个线程去完成一些外部要求完成的操作,即这个doSomething()方法。

DemoSimpleDidaDida类:

public class DemoSimpleDidaDida {
	private SimpleDidaDida dida;
	private int times = 0;
	
	public DemoSimpleDidaDida() {
		dida = new SimpleDidaDida(500) {
			@Override
			public void doSomething() {
				int time = ++times;
				try {
					System.out.println("第" + time + "次开始时间:" + System.currentTimeMillis());
					Thread.sleep(600);
					System.out.println("第" + time + "次结束时间:" + System.currentTimeMillis());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
	}
	
	public void runup() {
		dida.start();//开启定时器
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		dida.stop();//关闭定时器
	}
	
}

测试类Test:

public class Test {

	public static void main(String[] args) {
		DemoSimpleDidaDida demo = new DemoSimpleDidaDida();
		demo.runup();
	}

}

测试结果:

1次开始时间:15949633599812次开始时间:15949633604121次结束时间:15949633606443次开始时间:15949633610482次结束时间:15949633611344次开始时间:15949633614793次结束时间:15949633616605次开始时间:15949633619894次结束时间:15949633620836次开始时间:15949633625325次结束时间:15949633626127次开始时间:15949633630816次结束时间:15949633631438次开始时间:15949633635567次结束时间:15949633636919次开始时间:15949633641098次结束时间:159496336418910次开始时间:15949633645869次结束时间:159496336472610次结束时间:1594963365231

从结果可以看出,第一次还没结束,第二次已经开始了。因为我们设置的定时时间是0.5秒,当0.5秒一到,就开始执行doSomething()方法。但是这个doSomething()方法不一定能在0.5秒内执行完。在doSomething()方法中,先输出开始时间,然后等待0.6秒,再输出结束时间。所以本次的这个方法还没执行完,下一次已经开始了。这充分体现了我们所写的定时器就是只起定时作用,它不会去管你在这个时间片段内到底能不能完成这个操作,只要时间一到,就执行这个方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值