Personally, I feel that all software timing is done through polling, and opening a thread specifically to perform such a task consumes more resources. I feel that the following solution may have better performance.
0. First, we need a "scheduled broadcast" that sends a broadcast every 5 minutes 1. When the user registers, we register a listener to listen to the "scheduled broadcast" 2. If the user clicks on the activation address in the mailbox , then close the previously registered listener 3. If the listener receives the broadcast for the second time, it will execute the task and cancel the listening
The reason why the task must be executed when the broadcast is received for the second time is to ensure that the task can be executed after 5 to 10 minutes. Of course, this cannot guarantee accurate timing. If you need to improve the timing accuracy, you can broadcast once every minute, or even once every second, but this scenario should not be necessary.
To implement scheduled broadcast, you can use tools such as quartz, or even use message queues to separate this business.
Hope it helps, if there are any inappropriate or wrong parts, please feel free to comment
Use spring's timer to complete it at the service layer. There is a field in the database that is 0 when registering. After registration, call spring's timer to scan this field in the database every few seconds after five minutes and generate a verification code. The user clicked the address in the mailbox to stop the timer. I can give you the documentation and code of the spring timer
Paste a section of jdk's native timers and triggers. Timer and TimerTask are the key points. Register the listener when the timer calls the schedule or call it by other methods. For more, please refer to the JDK development documentation. There are detailed instructions in the documentation. This little demo of mine did not cancel the task.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Demo {
public static void main(String[] args) {
Timer timer = new Timer();
Long long1 =new Long("1486308200000");
timer.schedule(new TaskDemo(), new Date(long1));
}
}
class TaskDemo extends TimerTask{
@Override
public void run() {
System.out.println("点前时间是"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
}
}
It is more suitable to use message queue to implement this kind of one-time timer. It is relatively simple to implement, and there are mature solutions. The most indispensable thing in Java is the wheel. Message queues such as: RabbitMQ, ActiveMQ, RocketMQ
According to your design, each user's registration must start a scheduled task, so what if a large number of users register? A scheduled task is actually a thread. Starting a large number of threads will consume too much CPU resources.
The user clicks on the email address to activate the address and then destroy it. If you store scheduled tasks in the JVM, it is likely to fail during cluster deployment because you cannot guarantee that users access the same JVM instance during registration and activation.
The scheduled task finds that the user is not activated, and then regenerates the verification code. Why should it be generated before the user next clicks to send an email?
I think a better design should be like this:
User registration, user activation status = No
The user clicks [Send Activation Email], and the activation url is generated in the background. The url is accompanied by a uuid. This uuid is associated with the user name, stored (uuid, user name, expiration time), and then the email is sent
The user clicks the activation url in the email and accesses your application
Your application gets the uuid in the url to see if it exists in the database and has not expired. If yes, get the associated user name, update the user activation status = true, and delete the uuid; if no, do nothing.
uuid storage:
It can be stored in the database, but in order to clean up expired data, you can open a separate (only one) thread and run it every 1 minute to delete the expired uuid in the database.
It can also be stored in redis. Redis has a feature that you can specify the ttl of the data. It will be automatically deleted when it expires, so there is no need to open a separate thread to clean up the expired uuid.
Personally, I feel that all software timing is done through polling, and opening a thread specifically to perform such a task consumes more resources. I feel that the following solution may have better performance.
0. First, we need a "scheduled broadcast" that sends a broadcast every 5 minutes
1. When the user registers, we register a listener to listen to the "scheduled broadcast"
2. If the user clicks on the activation address in the mailbox , then close the previously registered listener
3. If the listener receives the broadcast for the second time, it will execute the task and cancel the listening
The reason why the task must be executed when the broadcast is received for the second time is to ensure that the task can be executed after 5 to 10 minutes. Of course, this cannot guarantee accurate timing. If you need to improve the timing accuracy, you can broadcast once every minute, or even once every second, but this scenario should not be necessary.
To implement scheduled broadcast, you can use tools such as quartz, or even use message queues to separate this business.
Hope it helps, if there are any inappropriate or wrong parts, please feel free to comment
Use the database to poll, and if clicked, delete the corresponding record
Use spring's timer to complete it at the service layer. There is a field in the database that is 0 when registering. After registration, call spring's timer to scan this field in the database every few seconds after five minutes and generate a verification code. The user clicked the address in the mailbox to stop the timer. I can give you the documentation and code of the spring timer
Paste a section of jdk's native timers and triggers. Timer and TimerTask are the key points. Register the listener when the timer calls the schedule or call it by other methods. For more, please refer to the JDK development documentation. There are detailed instructions in the documentation. This little demo of mine did not cancel the task.
It is more suitable to use message queue to implement this kind of one-time timer. It is relatively simple to implement, and there are mature solutions. The most indispensable thing in Java is the wheel. Message queues such as: RabbitMQ, ActiveMQ, RocketMQ
There is something wrong with your design:
According to your design, each user's registration must start a scheduled task, so what if a large number of users register? A scheduled task is actually a thread. Starting a large number of threads will consume too much CPU resources.
The user clicks on the email address to activate the address and then destroy it. If you store scheduled tasks in the JVM, it is likely to fail during cluster deployment because you cannot guarantee that users access the same JVM instance during registration and activation.
The scheduled task finds that the user is not activated, and then regenerates the verification code. Why should it be generated before the user next clicks to send an email?
I think a better design should be like this:
User registration, user activation status = No
The user clicks [Send Activation Email], and the activation url is generated in the background. The url is accompanied by a uuid. This uuid is associated with the user name, stored (uuid, user name, expiration time), and then the email is sent
The user clicks the activation url in the email and accesses your application
Your application gets the uuid in the url to see if it exists in the database and has not expired. If yes, get the associated user name, update the user activation status = true, and delete the uuid; if no, do nothing.
uuid storage:
It can be stored in the database, but in order to clean up expired data, you can open a separate (only one) thread and run it every 1 minute to delete the expired uuid in the database.
It can also be stored in redis. Redis has a feature that you can specify the ttl of the data. It will be automatically deleted when it expires, so there is no need to open a separate thread to clean up the expired uuid.