Fatal shortcomings of Timer in Java (with learning method)

table of Contents

Introduction

Case 1: The timer prints Hello World!

The thread is not dead?

Case 2: Single-threaded problem

Practical application scenarios of timers

Learning method experience

to sum up


Introduction


I have been struggling with this article whether I should write it or not. I don't want to write it because the timer usage is relatively simple, and the second is that I don't often ask during interviews. Later, I decided to write that I mainly wanted to share my analysis of the problem with everyone, so that everyone can refer to it during the learning process. I believe that most people have no problems with the learning attitude, especially the friends who are reading my blog post. ! ! Give you a crazy compliment. The next step is the learning method. I found that the learning posture of the little friend who recently consulted me was wrong, so I used the Timer in Java as a case to organize my learning method. The high-rise buildings rise on the ground, so I always use the easiest, easiest, and simplest case first! Let’s have a Hello World first!

image.png

 

 

 

 

Case 1: The timer prints Hello World!


import java.text.ParseException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author :jiaolian
 * @date :Created in 2021-01-05 20:42
 * @description:Timer启动后内置线程不销毁
 * @modified By:
 * 公众号:叫练
 */
public class TimerThreadNoStopTest {

    //TimerTask为抽象类,继承TimerTask类必须要实现里面抽象方法
    private static class Task extends TimerTask {
        @Override
        public void run() {
            System.out.println("hello world!");
        }
    }

    public static void main(String[] args) throws ParseException {

        Timer timer = new Timer();
        Task task = new Task();
        long currenTime = System.currentTimeMillis();
        //提交Task线程;程序按传入日期运行
        timer.schedule(task,new Date(currenTime));
    }
}

As in the above program code, Timer submits a task task and passes in the current time of currenTime, the console immediately prints "hello world!", if the second parameter passed in schedule is new Date (currenTime+2000), it means a delay of 2m To perform task tasks, the simple use method is not described too much here, but if you encounter doubts in the learning process, you must try to write more code tests. This is an essential part of understanding the code. Don’t think you can understand it. I won’t write anymore. Like when I’m learning, if I have a little doubt, I will immediately test the code by hand, because I know that sometimes I may understand, but that may not be true, only the code can be verified! The following figure is the printing result of the program console. If everyone executes it, you will find a problem. The program never stops running, that is, the program does not die. What caused this result?

image.png

 

The thread is not dead?


Reason analysis: As shown in the figure below, the main thread executes Timer timer = new Timer(); a new child thread timer is created. The timer thread takes the task task[1] in the queue through an endless loop. The queue is actually an array To implement TaskQueue, if there is no task in the queue, the timer thread will wait until the main thread calls schedule to submit the task. The main thread will add the task to the TaskQueue queue array and notify the timer thread to execute the task and delete the first task in the queue. If the main thread submits a timed task, it will re-add the task to the queue. After the task is executed, if the queue is empty at this time, the timer thread will continue to wait for the task to be submitted to the queue, and it will loop the above process. If you want to exit the timer thread, you can call the cancel method to exit the infinite loop . The reason why the thread does not die is that the timer thread has been waiting for the main thread to submit a task, and the communication between the timer thread and the main thread is achieved by calling wait/notify. We have introduced it in detail when we did the case of producer/consumer. I will not repeat the description here. You can go to the article "Example of Hen Laying Eggs" . During this process, we found that the timer is a single thread . What's wrong with my single thread? Is single thread also wrong? Consider a question. What if the timer submits two tasks in a single thread? Let's look at the code below!

image.png

 

 

Case 2: Single-threaded problem


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author :jiaolian
 * @date :Created in 2021-01-06 10:53
 * @description:多任务执行测试,任务只能顺序执行;
 * @modified By:
 * 公众号:叫练
 */
public class MultTaskExecuteTest {


    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static class  MyTask1 extends TimerTask {

        @Override
        public void run() {
            System.out.println("task1 begin:"+SIMPLE_DATE_FORMAT.format(new Date()));
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task1 end:"+SIMPLE_DATE_FORMAT.format(new Date()));
        }
    }

    private static class  MyTask2 extends TimerTask {

        @Override
        public void run() {
            System.out.println("task2 begin:"+SIMPLE_DATE_FORMAT.format(new Date()));
            System.out.println("task2 end:"+SIMPLE_DATE_FORMAT.format(new Date()));
        }
    }


    public static void main(String[] args){
        Timer timer = new Timer();
        MyTask1 myTask1 = new MyTask1();
        MyTask2 myTask2 = new MyTask2();
        long curTime = System.currentTimeMillis();
        System.out.println("当前时间:"+SIMPLE_DATE_FORMAT.format(curTime));
        timer.schedule(myTask1,new Date(curTime));
        //myTask1执行时间过长,myTask2 被执行时间会被延迟;
        timer.schedule(myTask2,new Date(curTime+1000));
    }

}

As shown in the above program code, the timer thread submits two tasks myTask1, myTask2, and myTask1 will be executed immediately, myTask2 is scheduled to be delayed for one second, and myTask1 will rest for 10 seconds during the execution. We observe the task execution time as shown in the figure below, myTask2 The task is executed after the task of myTask1 is executed. In fact, myTask2 is only delayed by one second, but the result is delayed by 10 seconds. This shows that the single thread of the timer will serialize the task and cause the delayed execution of myTask2, so Timer is suitable for lightweight timing. Tasks, if a large number of tasks are set, there may be delays in execution .

image.png

 

 

Practical application scenarios of timers


In the daily system development, I believe you have encountered similar tasks that need to be performed repeatedly, such as cleaning up the garbage data of a table in the database at 2 am every day , and the page display device (server) running status also needs to call the device status interface every 3 seconds. To query the device status, etc., the development of these functions requires the use of timers. Of course, the Timer timer also has its own shortcomings. For example, it is single-threaded. Later, I will talk about the timer in the thread pool is multi-threaded, and the Timer can be optimized. Therefore, mastering the Timer will lay a solid foundation for learning advanced content later. Knowing the reason, knowing the reason, we can be handy in practical applications!

 

 

Learning method experience


You can see that I have spent a lot of energy on analyzing multi-threading in recent articles, discussing issues such as visibility, atomicity, hens laying eggs, and consumption issues, because these features are the basis for understanding multi-threading, in my opinion. It is also very important, so I don’t think it is too much to write repeatedly. Before this, many novices or children with 2 to 3 years of work experience often asked me about the learning method of Java . There are also a large number of children’s shoes to do springboot as soon as they come up. , Ssm project, I do not recommend doing this, you must first understand the servlet, mvc idea, this is the basis before you do the project. My advice to them is to have a solid foundation, don’t learn advanced knowledge or frameworks, such as ReentrantLock source code, thread pool framework, just like you play a game, at the beginning you play the higher level of difficulty, once the slope is higher, you It will be more uncomfortable and laborious, let alone facing the book, this is the real process from getting started to giving up. At the same time, don’t just think about it when you’re studying, think you’ll pass this knowledge point by yourself. This is not enough. You need to write more code and practice more. You can deepen your understanding and memory of knowledge in the process. In fact, there is You seem to understand a lot of knowledge, but you haven't put it into practice, and you haven't really understood it . I don't recommend the method that you can't do it. I have been working for 7 years after graduating from my undergraduate degree and have been engaged in the front-line research and development of Java. , As a senior Java R&D engineer, I also brought a team in between, because I have walked through the pit, I still have a certain experience of learning programs, I will continue to organize and share some experience and knowledge in the days to come To everyone, I hope everyone likes to follow me. I'm called practicing, just start practicing when I call a slogan !

In summary, there are two sentences: do more, have a solid foundation, start simple, and then slowly go deeper!

 

 

to sum up


We use the code to briefly describe the timer timer submission task, and explain that the timer is a single-threaded light-weight timing task, which is its defect. In view of the limited space, there are still many methods of timer which we did not use code to post, such as timing execution, delayed execution, timer cancellation method, I hope you can execute it one by one in books, and I recommend this multithreading introductory learning book to everyone, "Java More "Core Technology of Thread Programming", the book is mainly based on cases, and there are no particularly difficult cases to understand, which is very suitable for novices to learn. If you need the pfd version, please contact me! If you like, please like and pay attention. My name is Lian [ Official Account ] , I call and practice.

image.png

 

 

Guess you like

Origin blog.csdn.net/duyabc/article/details/112346052