Javaタイマー
効果:
タイマーとは時間を計るために使うものです。次のような間隔で何かを行う必要がある場合に使用できます。
特定の Pinxixi Web サイトでのパニック買いを指定された期間内に終了する必要がある場合。
たとえば、特定の宝物のページを指定された期間内にページを更新する必要がある場合です。
目覚まし時計をセットすると、指定した時間に起きることができます。
実装原則:
Thread.sleep(long millis); このメソッドを呼び出すと、スレッドはミリ単位の長さの間スリープすることができます。
コードは次を示します。
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());
}
}
テストコード:
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();
}
}
}
試験結果
main 関数は 10 秒間スリープするため、スレッドは 10 回実行されます。各スレッド実行の結果間隔は 1 秒であるはずですが、その結果、2 回目と 3 回目の実行の結果は 1001 ミリ秒離れていることがわかります。6 回目と 7 回目の間隔は 1002 ミリ秒です。
start() で、つまりタイマーを開始するときに、 goon を true にして、無限ループ状態のスレッドを作成することで、 doSomething() を複数回実行できるようにし、そのたびに常にスリープ状態にします。実際には、delayTime ミリ秒
ごとに doSomething() を実行して、ユーザーのタスクの実行を開始します。
ただし、このアイデアにはまだ問題があります。 doSomething() は sleep() メソッドの後に実行され、次のタイミング ラウンドは doSomething() の実行が完了した後にのみ入力できるため、2 つの時間間隔はユーザー タスクの実行時間は次のようになります:
遅延時間 + ユーザー タスクにかかった時間
上記のエラーの根本原因は、時間になったらユーザー タスクを実行すべきではなく、ユーザー タスクを「開始」する必要があることです。ユーザータスクが正常に開始された直後に、タイマーを再起動し続けます。
これには、ユーザー タスクの実行に別のスレッドを使用する必要があります。
ユーザーコードを実行するためのインターフェース
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();
}
}
}
}
テストコード
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();
}
}
}