ฉันมีฟังก์ชั่นเฉพาะที่ฉันต้องการถูกเรียกใช้หลังจาก 5 วินาที ฉันจะทำสิ่งนั้นใน Java ได้อย่างไร
ฉันพบ javax.swing.timer แต่ฉันไม่เข้าใจวิธีการใช้งาน ดูเหมือนว่าฉันกำลังมองหาบางสิ่งที่ง่ายขึ้นแล้วคลาสนี้ก็จัดให้
โปรดเพิ่มตัวอย่างการใช้งานแบบง่าย
ฉันมีฟังก์ชั่นเฉพาะที่ฉันต้องการถูกเรียกใช้หลังจาก 5 วินาที ฉันจะทำสิ่งนั้นใน Java ได้อย่างไร
ฉันพบ javax.swing.timer แต่ฉันไม่เข้าใจวิธีการใช้งาน ดูเหมือนว่าฉันกำลังมองหาบางสิ่งที่ง่ายขึ้นแล้วคลาสนี้ก็จัดให้
โปรดเพิ่มตัวอย่างการใช้งานแบบง่าย
คำตอบ:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
แก้ไข:
javadocพูดว่า:
หลังจากการอ้างอิงสดครั้งสุดท้ายไปยังวัตถุตัวจับเวลาและการทำงานที่ค้างอยู่ทั้งหมดได้ดำเนินการเสร็จสิ้นแล้วเธรดการดำเนินงานของตัวจับเวลาจะสิ้นสุดลงอย่างสวยงาม (และอาจมีการรวบรวมขยะ) อย่างไรก็ตามการทำเช่นนี้อาจใช้เวลานานกว่าจะเกิดขึ้นโดยพลการ
import java.util.Timer; import java.util.TimerTask;
javax.swing.Timer
อาจทำให้มันชัดเจนมากว่านี้ไม่ได้ / หมายเหตุถ้าคุณใช้ Swing (และ AWT จริง ๆ ) คุณไม่ควรทำสิ่งใดเพื่อเปลี่ยนส่วนประกอบในเธรดที่ไม่ใช่เหตุการณ์ Dispatch Thread (EDT) ( java.util.Timer
งานไม่ดีjavax.swing.Timer
การกระทำที่ดี)
cancel
ในตอนท้ายของวิธีการเรียกใช้จะล้างเธรดการดำเนินการของ TimerTasks
บางสิ่งเช่นนี้
// When your program starts up
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// then, when you want to schedule a task
Runnable task = ....
executor.schedule(task, 5, TimeUnit.SECONDS);
// and finally, when your program wants to exit
executor.shutdown();
มีวิธีการอื่นจากโรงงานหลายวิธีExecutor
ที่คุณสามารถใช้แทนหากคุณต้องการเธรดเพิ่มเติมในพูล
และจำไว้ว่ามันเป็นสิ่งสำคัญที่จะต้องปิดผู้ปฏิบัติการเมื่อคุณทำเสร็จแล้ว shutdown()
วิธีการเรียบร้อยจะปิดตัวลงสระว่ายน้ำด้ายเมื่องานที่ผ่านมาได้เสร็จสมบูรณ์และจะป้องกันจนกระทั่งเกิดเหตุการณ์นี้ shutdownNow()
จะยกเลิกเธรดพูลทันที
ตัวอย่างการใช้งาน javax.swing.Timer
Timer timer = new Timer(3000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// Code to be executed
}
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!
รหัสนี้จะถูกดำเนินการเพียงครั้งเดียวและการดำเนินการจะเกิดขึ้นใน 3000 มิลลิวินาที (3 วินาที)
ในฐานะที่เป็น camickr กล่าวถึงคุณควรค้นหา " วิธีการใช้ตัวจับเวลาสวิง " สำหรับการแนะนำสั้น ๆ
รหัสของฉันเป็นดังนี้:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here, and if you have to refresh UI put this code:
runOnUiThread(new Runnable() {
public void run() {
//your code
}
});
}
},
5000
);
ในรูปแบบของ @tangens ตอบ: ถ้าคุณไม่สามารถรอให้ตัวรวบรวมขยะล้างเธรดของคุณให้ยกเลิกตัวจับเวลาในตอนท้ายของวิธีการเรียกใช้
Timer t = new java.util.Timer();
t.schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
// close the thread
t.cancel();
}
},
5000
);
Timer t
ประกาศfinal
เนื่องจากมีการเข้าถึงภายในชั้นในใช่หรือไม่
คำถามเดิมของคุณพูดถึง "Swing Timer" หากในความเป็นจริงคำถามของคุณเกี่ยวข้องกับ SWing คุณควรใช้ Swing Timer ไม่ใช่ตัวจับเวลา
อ่านหัวข้อจากบทช่วยสอนการแกว่งที่ " วิธีใช้ตัวจับเวลา " สำหรับข้อมูลเพิ่มเติม
คุณสามารถใช้ฟังก์ชัน Thread.Sleep ()
Thread.sleep(4000);
myfunction();
ฟังก์ชั่นของคุณจะทำงานหลังจาก 4 วินาที อย่างไรก็ตามสิ่งนี้อาจหยุดโปรแกรมทั้งหมดชั่วคราว ...
ScheduledThreadPoolExecutor
มีความสามารถนี้ แต่มันค่อนข้างหนา
Timer
ยังมีความสามารถนี้ แต่เปิดหลายเธรดแม้ว่าจะใช้เพียงครั้งเดียว
นี่คือการใช้งานง่าย ๆ ด้วยการทดสอบ (ลายเซ็นใกล้กับ Android's Handler.postDelayed () ):
public class JavaUtil {
public static void postDelayed(final Runnable runnable, final long delayMillis) {
final long requested = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
// The while is just to ignore interruption.
while (true) {
try {
long leftToSleep = requested + delayMillis - System.currentTimeMillis();
if (leftToSleep > 0) {
Thread.sleep(leftToSleep);
}
break;
} catch (InterruptedException ignored) {
}
}
runnable.run();
}
}).start();
}
}
ทดสอบ:
@Test
public void testRunsOnlyOnce() throws InterruptedException {
long delay = 100;
int num = 0;
final AtomicInteger numAtomic = new AtomicInteger(num);
JavaUtil.postDelayed(new Runnable() {
@Override
public void run() {
numAtomic.incrementAndGet();
}
}, delay);
Assert.assertEquals(num, numAtomic.get());
Thread.sleep(delay + 10);
Assert.assertEquals(num + 1, numAtomic.get());
Thread.sleep(delay * 2);
Assert.assertEquals(num + 1, numAtomic.get());
}
while
เป็นเพียงการละเว้นการหยุดชะงัก
คำตอบอื่น ๆ ทั้งหมดจำเป็นต้องเรียกใช้โค้ดของคุณภายในเธรดใหม่ ในกรณีที่ใช้ง่ายคุณอาจต้องรอสักครู่และดำเนินการต่อภายในเธรด / โฟลว์เดียวกัน
รหัสด้านล่างแสดงให้เห็นถึงเทคนิคที่ โปรดทราบว่าสิ่งนี้คล้ายกับสิ่งที่ java.util.Timer ทำภายใต้ประทุน แต่มีน้ำหนักเบากว่า
import java.util.concurrent.TimeUnit;
public class DelaySample {
public static void main(String[] args) {
DelayUtil d = new DelayUtil();
System.out.println("started:"+ new Date());
d.delay(500);
System.out.println("half second after:"+ new Date());
d.delay(1, TimeUnit.MINUTES);
System.out.println("1 minute after:"+ new Date());
}
}
DelayUtil Implementation
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class DelayUtil {
/**
* Delays the current thread execution.
* The thread loses ownership of any monitors.
* Quits immediately if the thread is interrupted
*
* @param duration the time duration in milliseconds
*/
public void delay(final long durationInMillis) {
delay(durationInMillis, TimeUnit.MILLISECONDS);
}
/**
* @param duration the time duration in the given {@code sourceUnit}
* @param unit
*/
public void delay(final long duration, final TimeUnit unit) {
long currentTime = System.currentTimeMillis();
long deadline = currentTime+unit.toMillis(duration);
ReentrantLock lock = new ReentrantLock();
Condition waitCondition = lock.newCondition();
while ((deadline-currentTime)>0) {
try {
lock.lockInterruptibly();
waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
} finally {
lock.unlock();
}
currentTime = System.currentTimeMillis();
}
}
}
public static Timer t;
public synchronized void startPollingTimer() {
if (t == null) {
TimerTask task = new TimerTask() {
@Override
public void run() {
//Do your work
}
};
t = new Timer();
t.scheduleAtFixedRate(task, 0, 1000);
}
}