Programming

java : 특정 시간 (초) 후에 함수 실행

procodes 2020. 6. 28. 20:09
반응형

java : 특정 시간 (초) 후에 함수 실행


5 초 후에 실행하려는 특정 기능이 있습니다. Java로 어떻게 할 수 있습니까?

javax.swing.timer를 찾았지만 사용법을 이해할 수 없습니다. 이 클래스가 제공하는 것보다 더 간단한 방법을 찾고있는 것 같습니다.

간단한 사용 예를 추가하십시오.


new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        5000 
);

편집하다:

javadoc 는 말한다 :

Timer 객체에 대한 마지막 실시간 참조가 사라지고 모든 미해결 작업이 실행을 완료하면 타이머의 작업 실행 스레드가 정상적으로 종료됩니다 (가비지 수집 대상이 됨). 그러나이 문제가 발생하는 데 시간이 오래 걸릴 수 있습니다.


이 같은:

// 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!

이 코드는 한 번만 실행되며 3000ms (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의 변형으로 가비지 수집기가 스레드를 정리할 때까지 기다릴 수 없으면 run 메소드 끝에서 타이머를 취소하십시오.

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 
);

Your original question mentions the "Swing Timer". If in fact your question is related to SWing, then you should be using the Swing Timer and NOT the util.Timer.

Read the section from the Swing tutorial on "How to Use Timers" for more information.


you could use the Thread.Sleep() function

Thread.sleep(4000);
myfunction();

Your function will execute after 4 seconds. However this might pause the entire program...


ScheduledThreadPoolExecutor has this ability, but it's quite heavyweight.

Timer also has this ability but opens several thread even if used only once.

Here's a simple implementation with a test (signature close to 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() {
                while (true) {
                    try {
                        long leftToSleep = requested + delayMillis - System.currentTimeMillis();
                        if (leftToSleep > 0) {
                            Thread.sleep(leftToSleep);
                        }
                        break;
                    } catch (InterruptedException ignored) {
                    }
                }
                runnable.run();
            }
        }).start();
    }
}

Test:

@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());
}

All other unswers require to run your code inside a new thread. In some simple use cases you may just want to wait a bit and continue execution within the same thread/flow.

Code below demonstrates that technique. Keep in mind this is similar to what java.util.Timer does under the hood but more lightweight.

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);
        }
    }

참고URL : https://stackoverflow.com/questions/2258066/java-run-a-function-after-a-specific-number-of-seconds

반응형