Multiple Realization Methods of Java Timer

  • 2021-09-11 20:20:37
  • OfStack

Catalogue 1. Preface
(1) Timer
(2) DelayedQueue delay queue
(3) ScheduledThreadPoolExecutor
(4) ScheduledThreadPoolExecutor

1. Preface

There are three forms of timer:

Execute regularly at a fixed period Delay 1 time and execute Specify a time to execute

JDK provides three commonly used timer implementations, namely:

Timer DelayedQueue Delay queue ScheduledThreadPoolExecutor

(1) Timer

Discover eureka Is widely used in Timer Timer:

Timer belongs to the implementation of an earlier version of JDK, which can realize fixed-cycle tasks as well as delayed tasks. Timer will start an asynchronous thread to execute the expired task, which can only be scheduled to be executed once, or it can be executed repeatedly periodically.

The sample code for how Timer is used is as follows:


Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //  Business code 
    }
}, 5000, 5000);  // 5s  Post-scheduling 1 The cycles are  5s  Timed tasks of 
TimerTask Is realized Runnable Abstract class of interface Timer Responsible for scheduling and execution TimerTask

Timer The internal structure of is as follows:


public class Timer {
    //  Small roots, run Operation  O(1) , new  O(logn) , cancel O(logn)
    private final TaskQueue queue = new TaskQueue();
    //  Create another thread, task processing, polling  queue
    private final TimerThread thread = new TimerThread(queue);
    public Timer(String name) {
        thread.setName(name);
        thread.start();
    }
}

Timer It has many design flaws, so it is not recommended for users to use:

Timer Is single-threaded mode, if a TimerTask It takes a long time to execute, which will affect the scheduling of other tasks. Timer Task scheduling is based on the absolute time of the system. If the system time is incorrect, problems may occur. TimerTask If an exception occurs in execution, Timer It will not be captured, causing the thread to terminate and other tasks will never be executed.

(2) DelayedQueue delay queue

The characteristics are as follows:

DelayedQueue It is a blocking queue in JDK that can delay obtaining objects, and its internal priority queue is adopted PriorityQueue Storage object DelayQueue Each object in must implement the Delayed Interface and override the compareTo And getDelay Method

DelayedQueue The use method of is as follows:


public class DelayQueueTest {
    public static void main(String[] args) throws Exception {
        BlockingQueue<SampleTask> delayQueue = new DelayQueue<>();
        long now = System.currentTimeMillis();
        delayQueue.put(new SampleTask(now + 1000));
        delayQueue.put(new SampleTask(now + 2000));
        delayQueue.put(new SampleTask(now + 3000));
        for (int i = 0; i < 3; i++) {
            System.out.println(new Date(delayQueue.take().getTime()));
        }
    }
    static class SampleTask implements Delayed {
        long time;
        public SampleTask(long time) {
            this.time = time;
        }
        public long getTime() {
            return time;
        }
        @Override
        public int compareTo(Delayed o) {
            return Long.compare(this.getDelay(TimeUnit.MILLISECONDS), o.getDelay(TimeUnit.MILLISECONDS));
        }
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }
    }
}

(3) ScheduledThreadPoolExecutor

JDK Provides a more functional ScheduledThreadPoolExecutor


public class ScheduledExecutorServiceTest {
    public static void main(String[] args) {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
        executor.scheduleAtFixedRate(() -> System.out.println("Hello World"), 1000, 2000, TimeUnit.MILLISECONDS); // 1s  Start executing the task after delay, and every  2s  Repeated execution 1 Times 
    }
}

ScheduledThreadPoolExecutor Blocking queues are used DelayedWorkQueue .

(4) ScheduledThreadPoolExecutor

Thread should be the most common implementation scheme, create a thread to perform tasks, for example, several different writing, the code is as follows

4.1. Using thread + runnable


package com.yezi_tool.demo_basic.test;

import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class ThreadTest {

    private Integer count = 0;

    public ThreadTest() {
        test1();
    }

    public void test1() {
        new Thread(() -> {
            while (count < 10) {
                System.out.println(new Date().toString() + ": " + count);
                count++;
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

4.2. Using Thread Pool + runnable


package com.yezi_tool.demo_basic.test;

import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class ThreadTest {

    private static final ExecutorService threadPool = Executors.newFixedThreadPool(5);//  Thread pool 
    private Integer count = 0;

    public ThreadTest() {
        test2();
    }

    public void test2() {
        threadPool.execute(() -> {
            while (count < 10) {
                System.out.println(new Date().toString() + ": " + count);
                count++;
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

The above is the Java timer implementation of a variety of details, more information about the implementation of Java timer please pay attention to other related articles on this site!


Related articles: