Recently, I have organized my personal study notes into a book and shared them in PDF, which mainly covers Java basics, data structures, JVM, multi-threading, etc. Due to the limited space, only a few interview questions are shown below.

Friends in need can point to get:Click here to get it…Cipher: JJ

六四屠杀

Scheduled

Suitable for simple scheduled tasks, not distributed scheduled tasks. Advantages: The Spring framework provides planning tasks, which are easy to develop and efficient to execute. When the number of scheduled tasks is too large, problems such as blocking, crash, and delayed startup may occur.

Scheduled Scheduled tasks are Scheduled tasks that come with spring3.0. The Spring resource package is spring-context-support. To use the Scheduled task mechanism, you need to rely on the following resources:

<! <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>Copy the code

If you need to enable Scheduled tasks in your Spring application, you need to add the @enablesCheduling annotation to your startup class to enable Scheduled tasks. Details are as follows:

@SpringBootApplication @EnableScheduling public class AppStarter { public static void main(String[] args) { SpringApplication.run(AppStarter.class, args); }}Copy the code

Scheduled The heart of Scheduled tasks is the @Scheduled annotation. The core attribute of this annotation is cron, which represents a Scheduled trigger expression for Scheduled tasks. The format of this expression is:

@Scheduled(cron="seconds minutes hours day month week")
Copy the code

or

@Scheduled(cron="seconds minutes hours day month week year")
Copy the code

The first expression form is recommended because there are different scheduled task mechanisms in many other technologies, and the expressions used to set the trigger schedule are the first CRON expressions. The second expression is not specific to Spring Scheduled and is supported only by a few technologies.

The constraint for each position in the CRON expression is as follows:

The asterisk (*) is used in all fields to indicate each moment in the corresponding time domain. For example, the asterisk (*) in the minute field indicates every minute.

Question mark : This character is used only in the date and week fields and is usually specified as a “meaningless value”, which is equivalent to a placeholder;

The minus sign (-) indicates a range. For example, if “10-12” is used in the hour field, it indicates the range from 10 to 12, namely 10,11,12.

Comma (,) : indicates a list value. For example, if “MON,WED,FRI” is used in the week field, it indicates Monday, Wednesday, and Friday.

Slash (/) : x/y expresses a sequence of equal step sizes, where x is the starting value and y is the incremental step size. Using 0/15 in seconds is 0,15,30, and 45 seconds, while 5/15 in minutes is 5,20,35,50. You can also use */y, which is the same as 0/y;

L: This character is only used in the date and week fields and stands for “Last”, but it has a different meaning in the two fields. L In the date field, indicates the last day of the month, such as the 31st day of January or the 28th day of February in a non-leap year. If L is used during the week, it means Saturday, which is the same as 7. However, if L appears in the week field and is preceded by a numerical value X, it means “the last X day of the month”. For example, 6L means the last Friday of the month;

W: This character can only appear in the date field. It modifies the leading date and indicates the working day closest to the date. For example, 15W indicates the closest working day to the 15th of the month. If the 15th of the month falls on a Saturday, Friday the 14th is matched. If the 15th falls on a Sunday, it matches Monday the 16th; If the 15th is Tuesday, it turns out to be Tuesday the 15th. If you specify 1W, if the 1st is a Saturday, the result will be Monday the 3rd, not the last day of the last month. The W string can only specify a single date, not a range of dates;

LW combination: You can combine LW in the date field, which means the last business day of the month;

Pound sign (#) : This character can only be used in the week field to indicate a day of the month. For example, 6#3 indicates the third Friday of the month (6 indicates Friday, #3 indicates the current third), and 4#5 indicates the fifth Wednesday of the month.

C: This character is only used in the date and week fields and represents the meaning of “Calendar”. It means the date to which the plan is associated, or if the date is not associated, all dates in the calendar. For example 5C in the date field corresponds to the first day after the 5th day of the calendar. 1C in the week field corresponds to the day after Sunday.

Cron expressions are case-insensitive to special characters, and case-insensitive to abbreviations of the week.

Scheduled tasks are implemented through a thread pool. It’s a multithreaded schedule. SpringBoot initializes a thread pool, with a default size of 1, dedicated to executing scheduled tasks. When each scheduled task is started, a thread is fetched from the thread pool to execute. If an exception occurs, only the thread executing the current task will fail, not the scheduled task scheduling thread. If the current scheduled task is not completed and the same scheduled task enters the execution period, no new scheduled task is triggered. Such as:

@Scheduled(cron="* * * * * ?")
public void test1(){    
Random r = new Random();    
/*int i = r.nextInt(100);   
 if(i % 3 == 0){        
throw new RuntimeException("error");   
 }*/    
System.out.println(Thread.currentThread().getName() + " cron=* * * * * ? --- " + new Date());    
try{       
 Thread.sleep(2000);   
 }catch(Exception e){       
 e.printStackTrace();  
  }
}
Copy the code

As shown in the result (the thread name is the same each time, because the previous scheduled task is not completed, so the next task is postponed, instead of executing once every second, but 3 seconds) :

pool-1-thread-1 cron=* * * * * ? --- Thu Sep 19 02:23:20 CST 2019
pool-1-thread-1 cron=* * * * * ? --- Thu Sep 19 02:23:23 CST 2019
pool-1-thread-1 cron=* * * * * ? --- Thu Sep 19 02:23:26 CST 2019
pool-1-thread-1 cron=* * * * * ? --- Thu Sep 19 02:23:29 CST 2019
Copy the code

quartz

Quartz is another open source project in the Job Scheduling area from the OpenSymphony open source organization, and it can be used in combination with J2EE and J2SE applications or on its own. Quartz can be used to create programs as simple or complex as running ten, hundreds, or even tens of thousands of Jobs.

Quartz is an open source job scheduling framework written entirely in Java. Don’t let the term job scheduling scare you. While the Quartz framework incorporates a lot of extra features, in its simple form, it’s incredibly easy to use!

When developing A Quartz application, a scheduled scheduling capability can be implemented by defining jobs, triggers and schedulers. Among them, Scheduler is the core of Quartz, which is responsible for managing the runtime environment of Quartz application. Instead of completing all the work by itself, Scheduler calls the task execution logic in Job according to the triggering standard of Trigger to complete the complete scheduled task scheduling.

Job – What is the content of the scheduled task. Trigger – When the job is executed. Scheduler – Maintains the scheduled task environment and activates triggers.

To apply Quartz in SpringBoot, you need to rely on the following resources:

<dependencies> <! -- Scheduled resources are spring-context-support, and spring support for Quartz is integrated into the spring-context-support package. org.springframework.scheduling.quartz --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <! Scheduler </groupId> <artifactId> Quartz </artifactId> The < version > 2.2.1 < / version > <! Quartz requires SLF4J support by default. Springboot, Slf4j -> < Exclusions > <artifactId> SLf4J-API </artifactId> <groupId>org.slf4j</groupId> </ Exclusion > </exclusions> </dependency> <! -- Spring TX coordinates, Quartz can provide distributed timing task environment. Quartz tasks at multiple distribution points are transmitted through the database. Data in the database ensures that only one distributed environment performs scheduled tasks at a time. --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency></dependencies>Copy the code

Initiators add comments @enablescheduling:

/** * @enablesCheduling Required * Enable the scheduled task mechanism. */@SpringBootApplication@EnableScheduling public class AppStarter { public static void main(String[] args) { SpringApplication.run(AppStarter.class, args); }}Copy the code

Define JOB tasks and mock business objects called by JOB tasks:

Public class SpringBootQuartzJobDemo implements Job {// Used to simulate a business object in a task. It could also be a data access object, or some other type of object. @Autowired private CommonsUtil4Quartz commonsUtil4Quartz; @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("SpringBootQuartzJobDemo : " + new Date()); this.commonsUtil4Quartz.testMethod(); } } @Component public class CommonsUtil4Quartz { public void testMethod(){ System.out.println("CommonsUtil4Quartz testMethod run..." ); }}Copy the code

Create Trigger and JobDetail objects and use Schedule to configure the scheduled task:

/** * Initialization class * Quartz environment initialization. ** / @configuration public class QuartzConfiguration {/** * Create a Job object. In the Spring environment, when you create objects of a type, in many cases you create them indirectly through FactoryBeans. * If there are multiple Job objects, define multiple methods. * * The underlying logic used to create the JobDetail object in JobDetailFactoryBean type is class.newinstance () * that is, the JobDetail object is not managed by the Spring container. * Because the Spring container does not manage the JobDetail object, there is no automatic state for the properties in the Job that need to be auto-assembled. The null pointer exception is reported on line 10 of the previous JOB. The solution is to add JobDetail to the Spring container and let the Spring container manage the JobDetail object. * Factory code needs to be rewritten. Implement Spring container management of JobDetail. * @return */ @Bean public JobDetailFactoryBean initJobDetailFactoryBean(){ JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); // Provide the job type. factoryBean.setJobClass(SpringBootQuartzJobDemo.class); return factoryBean; } /** * manage Trigger objects * CronTrigger - is an implementation of Trigger. The CronSchedulerBuilder that defines the cycle time is actually the CronTrigger type used to manage a Cron expression. * @param jobDetailFactoryBean - The jobDetailFactoryBean initialized by the previous method * @return */ @bean (name="cronTriggerFactoryBean1") public CronTriggerFactoryBean initCronTriggerFactoryBean( ){ CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();  JobDetailFactoryBean jobDetailFactoryBean = this.initJobDetailFactoryBean(); factoryBean.setJobDetail(jobDetailFactoryBean.getObject()); factoryBean.setCronExpression("0/3 * * * * ?" ); return factoryBean; } /** * init Scheduler * @param cronTriggerFactoryBean - the cronTriggerFactoryBean initialized by the previous method * @return */ @bean public SchedulerFactoryBean initSchedulerFactoryBean( CustomJobFactory customJobFactory, CronTriggerFactoryBean[] cronTriggerFactoryBean){ SchedulerFactoryBean factoryBean = new SchedulerFactoryBean(); CronTrigger[] triggers = new CronTrigger[cronTriggerFactoryBean.length]; for(int i = 0; i < cronTriggerFactoryBean.length; i++){ triggers[i] = cronTriggerFactoryBean[i].getObject(); } // Register triggers. A Scheduler can register several triggers. factoryBean.setTriggers(triggers); // Sets the JobDetail factory for Scheduler. You can override the default factory provided by SpringBoot to ensure that the autowage in JobDetail works. factoryBean.setJobFactory(customJobFactory); return factoryBean; }}Copy the code

Rewrite JobFactory:

/** * rewrites the factory object. */ @Component public class CustomJobFactory extends AdaptableJobFactory { /** * AutowireCapableBeanFactory : Spring container is a Bean object management project of the Spring container Context. * Can implement automatic assembly logic, and object creation logic. * is an important component of the SpringIoC container. */ @Autowired private AutowireCapableBeanFactory autowireCapableBeanFactory; @override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {// Create the JobDetail Object using the method specified in the parent type. Object obj = super.createJobInstance(bundle); // Add the JobDetail object to the Spring container, let the Spring container manage it, and implement auto-assembly logic. this.autowireCapableBeanFactory.autowireBean(obj); return obj; }}Copy the code

Distributed Quartz configuration

1. Resource dependency configuration: For distributed reasons, Quartz provides jar packages for distributed processing and database and connection dependencies.

<dependencies> <! <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <! Scheduler </groupId> <artifactId> Quartz </artifactId> <version>2.2.1</version> <exclusions> <artifactId> slf4J-API </artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <! -- is a Jar in Quartz that provides distributed processing. --> <dependency> <groupId>org. Quartz -scheduler</groupId> <artifactId> Quartz -jobs</artifactId> <version>2.2.1</version> </dependency> <! Sprng tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <! GroupId > <artifactId> Spring-boot-starter -web</artifactId> </dependency> <! --jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <! --mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <! Druid <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency></dependencies>Copy the code

2. Provide database-related configuration:

spring.datasource.url=jdbc:mysql://localhost:3306/quartz? autoReconnect=true&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 spring.datasource.maxWait=600000 spring.datasource.timeBetweenEvictionRunsMillis=600000 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=falseserver.port=8080Copy the code

3. Provide Quartz configuration information. Provide database configuration information for Quartz, such as database, table prefixes, etc.

# whether to use the properties as the data storage org. Quartz jobStore. UseProperties = false # in the database table name prefix org. Quartz. JobStore. TablePrefix = QRTZ_ # Whether a cluster, is the task of distributed org. Quartz. JobStore. IsClustered = true # cluster inspection cycle, unit of milliseconds. You can customize the shortening time. When a node is down, how long do other nodes wait to execute tasks? . Org. Quartz. JobStore clusterCheckinInterval milliseconds = 5000 # unit, ended the nodes in the cluster, check again to enter the time interval. . Org. Quartz. JobStore misfireThreshold = 60000 # transaction isolation level org. Quartz. JobStore. TxIsolationLevelReadCommitted = true # Storage type of transaction management org. Quartz. JobStore. Class = org. Quartz. Impl. Jdbcjobstore. JobStoreTX # use Delegate types Org. Quartz. JobStore. DriverDelegateClass = org. Quartz. The impl. Jdbcjobstore. # StdJDBCDelegate cluster name, a cluster to have the same name. Org. Quartz. The scheduler. InstanceName = # ClusterQuartz node name, you can customize. AUTO indicates automatic generation. Org. Quartz. The scheduler. InstanceId = # AUTO rmi remote agreement whether released org.. Quartz scheduler. The rmi. The export = false # rmi remote protocol agent is created Org. Quartz. The scheduler, rmi proxy = false # whether to use the control of the user transaction environmental trigger job execution. org.quartz.scheduler.wrapJobExecutionInUserTransaction = falseCopy the code

Initialize the database

Table syntax can be found in the official website (Quartz-lib), using tables-mysql.sql to create tables.

Define the JOB class

The launcher is the same as regular Quartz, but the JOB definition itself is slightly different:

/** * Implement Job definitions using Spring's Quartz related Job types. * The parent type QuartzJobBean provides configuration definitions for tasks in a distributed environment. * Ensure that tasks in a distributed environment are efficient. * / @ PersistJobDataAfterExecution / / when the end of the job execution, Persistent job information to the database @ DisallowConcurrentExecution / / that the uniqueness of the job (singleton) public class SpringBootQuartzJobDemo extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("SpringBootQuartzJobDemo : " + new Date()); }}Copy the code

6. QuartzConfiguration type definition

@Configuration public class QuartzConfiguration { @Autowired private DataSource dataSource; /** * create scheduler, can be omitted. * @return * @throws Exception */ @Bean public Scheduler scheduler() throws Exception { Scheduler scheduler = schedulerFactoryBean().getScheduler(); scheduler.start(); return scheduler; } /** * Creates the scheduler factory bean object. * @return * @throws IOException */ @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setSchedulerName("Cluster_Scheduler"); factory.setDataSource(dataSource); factory.setApplicationContextSchedulerContextKey("applicationContext"); // Set the thread pool in the scheduler. factory.setTaskExecutor(schedulerThreadPool()); // Set trigger factory.settriggers (trigger().getobject ()); / / set the configuration information of quartz factory. SetQuartzProperties (quartzProperties ()); return factory; } /** * How to read the Quartz. Properties configuration file. * @return * @throws IOException */ @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean  propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); / / in quartz. The properties of the property is read and initializes the object again after injection propertiesFactoryBean. AfterPropertiesSet (); return propertiesFactoryBean.getObject(); } /** * The method to create the Job object. * @return */ @Bean public JobDetailFactoryBean job() { JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setJobClass(SpringBootQuartzJobDemo.class); / / whether the persistent job contents jobDetailFactoryBean. SetDurability (true); // Sets whether to try the task multiple times. jobDetailFactoryBean.setRequestsRecovery(true); return jobDetailFactoryBean; } /** * Creates the Trigger Factory bean object. * @return */ @Bean public CronTriggerFactoryBean trigger() { CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setJobDetail(job().getObject()); cronTriggerFactoryBean.setCronExpression("0/2 * * * * ?" ); return cronTriggerFactoryBean; } /** * Create a scheduler thread pool. * @return */ @Bean public Executor schedulerThreadPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(15); executor.setMaxPoolSize(25); executor.setQueueCapacity(100); return executor; }}Copy the code

If the JOB task defines the calling service, it also needs to rewrite JobFactory, such as the conventional Quartz, which is not described here.

Biography: Swing unruly, love life. Java Cultivator (wechat official ID: Java Cultivator), welcome to follow. Access to 2000G of detailed information on the 2020 interview questions