关于滴答滴答定时器的一些问题

时间:2024-03-17 09:30:10

在前些天的学习中,感觉到线程是非常非常的重要,所以写了一个关于线程调用的问题,具体如下:

现在,有这么个需求,我需要做一个定时器,每1000ms也就是1S响一下,或者说执行我们所给的操作(示例中只是简单的输出了一下)

一般情况的做法是: 我们给出一个线程,让它等待1000ms,完了之后执行我们给的dosomething()方法,用来执行我们的操作;

乍一看,这个处理方法好像没有什么问题,但是仔细想想就有问题了,如果只有一个线程,那么当计时器线程工作的时候,我们只能干等,时间到了才能执行,但是如果这个方法执行比较耗时,我们方法还没完的时候计时器又到了下一个时间点,那么又只能干等着上一次的方法执行完,这样我们的代码效率无疑是非常低效的;

新思路的做法: 我可以给出两个线程,一个是滴答滴答的计时器线程,另一个是worker线程,同时给他们加上一个共同的synchronized (lock);什么意思呢?就是说,我让一个线程专门计时,时间到了,它的任务不是执行dosomething()方法,二是notify(),即唤醒相同对象锁下的线程,也就是唤醒worker,而在worker中执行dosomething()方法,这样的优点在于避免了我们上面提到的错误,同时让代码变得非常高效;

代码示例如下:
Didadida类:

public abstract class Didadida implements Runnable {
	private Object lock;
	private volatile boolean goon = false;
	private long delayTime; 
	public static final long DEFAULT_TIME = 1000;
	
	
	public abstract void dosomething();
	
	public Didadida() {
		this.lock = new Object();
		this.delayTime = DEFAULT_TIME;
	}
	

	
	public Didadida setDelayTime(long delayTime) {
		this.delayTime = delayTime;
		return this;
	}

	public void startClock() {
		if(goon == true) {
			return;
		}
		goon = true;
		new DidaWorker();
		new Thread(this,"滴答滴答").start();
	}
	
	public void stop() {
		if(goon == false) {
			return;
		}
		goon = false;
	}


	@Override
	public void run() {
		while(goon) {
			synchronized (lock) {
				try {
					lock.wait(delayTime);
					System.out.println(delayTime+"ms到!");
					lock.notifyAll();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	class DidaWorker implements Runnable{
		public DidaWorker() {
			new Thread(this,"worker").start();
		}
		@Override
		public void run() {
			while(goon) {
				synchronized (lock) {
					try {
						lock.wait();
						dosomething();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}

			}
		}
		
	}
}

Test类:

public class test  {
	
	public static void main(String[] args) {
		
		Didadida didadida = new Didadida() {
			@Override
			public void dosomething() {
				System.out.println(System.currentTimeMillis());
				}		
		}.setDelayTime(100);
		didadida.startClock();

	}

}

截图如下:

关于滴答滴答定时器的一些问题