Tick Tock - Java Timer

Java timer

effect:

A timer is something that is used to keep time. You can use it when you need to do something at intervals, such as:

When the panic buying on a certain Pinxixi website needs to end within a specified period of time.
For example, when the page of a certain treasure needs to refresh the page within a specified period of time.
When you set the alarm clock to wake you up at the specified time.

Implementation principle:

Thread.sleep(long millis); Calling this method allows the thread to sleep for the length of millis.

The code shows:

package com.dxc.simple_dida.core.core;

public interface ISimpleDiDa {
    
    
	void doSomething();
}

package com.dxc.simple_dida.core.core;

public class SimpleDiDa implements Runnable, ISimpleDiDa{
    
    
	
	private long delayTime;
	private boolean goon;//当goon为TRUE线程启动,为false线程关闭。
	int count;
	
	public SimpleDiDa() {
    
    
	}

	//设置线程休眠时间
	public void setDelayTime(long delayTime) {
    
    
		this.delayTime = delayTime;
	}
	
	//启动线程
	public void startup() {
    
    
		this.goon = true;	
		new Thread(this).start();
	}
	
	//计时器以规定的时间间隔
	public void run() {
    
    
		while (goon) {
    
    
			try {
    
    
				Thread.sleep(this.delayTime);
				doSomething();//这里可以执行接口里面的方法
			} catch (InterruptedException e) {
    
    
				e.printStackTrace();
			}
		}
	}
	
	//停止线程
	public void stop() {
    
    
		this.goon = false;
	}

	//设置接口方法实现的内容
	//这里我输出一下时间,时间单位为毫秒
	@Override
	public void doSomething() {
    
    
		System.out.println("第" + ++this.count
				+ "次执行:" + System.currentTimeMillis());
	}
}

Test code:

package com.dxc.simple_dida.core.core;

public class Test {
    
    

	public static void main(String[] args) {
    
    
		SimpleDiDa sdd = new SimpleDiDa();
		sdd.setDelayTime(1000);	//设置线程执行时间间隔为一秒
		sdd.startup();//启动线程
		try {
    
    
			Thread.sleep(10000);
			//让主函数睡眠十秒钟,以便执行上面启动的线程
			sdd.stop();//主函数休眠结束,关闭执行线程
		} catch (InterruptedException e) {
    
    
			e.printStackTrace();
		}
	}
}

Test Results

Results of the
The main function sleeps for ten seconds, so the thread executes ten times. The result interval of each thread execution should be one second, but as a result we can see that the results of the second and third executions are separated by 1001 milliseconds. The interval between the sixth and seventh times is 1002 milliseconds.

In startup(), that is, when starting the timer, let goon be true, and create a thread, which is in an endless loop state, so that doSomething() can be executed multiple times; and, each time, it always sleeps for delayTime milliseconds, and
then Execute doSomething(), in fact, every delayTime milliseconds, start to execute the user's task.

However, there are still problems with this idea: because doSomething() is executed after the sleep() method, and the next round of timing can only be entered after the execution of doSomething() is completed, so that the time interval between two executions of user tasks should be is:
delayTime + time spent by user tasks

The root cause of the above error is: the user task should not be executed when the time comes, but the user task should be "started"! Immediately after starting the user task successfully, continue to restart the timer!
This requires that for user tasks, another thread should be used to execute them!

Interface to execute user code

package com.dxc.senior_dida.core;

public interface ISeniorDiDa extends Runnable{
    
    
	@Override
	default void run() {
    
    
		doSomething();
	}
	
	void doSomething();
}

package com.dxc.senior_dida.core;

public class SeniorDiDa implements Runnable {
    
    
	public static final long DEFAULT_DELAY_TIME = 1000;
	
	private long delayTime;
	private volatile boolean goon;
	private ISeniorDiDa worker;//用户执行的代码
	
	public SeniorDiDa() {
    
    
		this.delayTime = DEFAULT_DELAY_TIME;
	}
	
	//添加用户执行代码
	public SeniorDiDa setWorker(ISeniorDiDa worker) {
    
    
		this.worker = worker;
		return this;
	}

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

	//启动线程
	public void startup() {
    
    
		if (this.goon == true) {
    
    
			return;
		}
		if (this.worker == null) {
    
    
			return;
		}
		this.goon = true;
		new Thread(this).start();
	}
	
	//关闭线程
	public void stop() {
    
    
		if (this.goon == false) {
    
    
			return;
		}
		this.goon = false;
	}
	
	@Override
	public void run() {
    
    
		while (goon) {
    
    
			try {
    
    
				//线程睡眠delaytime时间
				Thread.sleep(this.delayTime);
				//线程睡眠期间,启动并执行用户要执行的代码
				new Thread(this.worker).start();
			} catch (InterruptedException e) {
    
    
				e.printStackTrace();
			}
		}
	}
	
}

test code

package com.dxc.senior_dida.core;

public class Test {
    
    

	public static void main(String[] args) {
    
    
		//设置用户要执行的代码
		ISeniorDiDa worker = new ISeniorDiDa() {
    
    
			private int count = 0;
			
			@Override
			public void doSomething() {
    
    
				System.out.println("第" + ++this.count
						+ "次执行:" + System.currentTimeMillis());
			}
		};
		
		SeniorDiDa seniorDiDa = new SeniorDiDa()
				.setWorker(worker);
		seniorDiDa.startup();//启动线程
		try {
    
    
			Thread.sleep(10000);//主函数睡眠10000毫秒
			seniorDiDa.stop();//线程停止
		} catch (InterruptedException e) {
    
    
			e.printStackTrace();
		}
	}

}

Guess you like

Origin blog.csdn.net/adaizzz/article/details/109268076