Java regular tasks Quartz (three) - Concurrent

1 Introduction

According Quartz design, a Job can bind multiple Trigger, will inevitably encounter concurrency issues.

2 Concurrent

2.1 reproducibility

Let's write an example of concurrency:

 1 /**
 2  * @author pancc
 3  * @version 1.0
 4  */
 5 public class AcceptConcurrentDemo {
 6 
 7     public static void main(String[] args) throws SchedulerException, InterruptedException {
 8         JobDetail detail = JobBuilder.newJob(AcceptConcurrentJob.class)
 9                 .withIdentity("detail", "group0")
10                 .build();
11 
12 
13         Trigger trigger = TriggerBuilder.newTrigger()
14                 .withIdentity("ben_trigger")
15                 .usingJobData("name", "ben")
16                 .startNow()
17                 .build();
18 
19         Trigger triggers = TriggerBuilder.newTrigger()
20                 .withIdentity("mike_trigger")
21                 .usingJobData("name", "mike")
22                 .forJob("detail", "group0")
23                 .startNow()
24                 .build();
25 
26 
27         Scheduler scheduler = new StdSchedulerFactory().getScheduler();
28 
29         scheduler.start();
30         scheduler.scheduleJob(detail, trigger);
31         scheduler.scheduleJob(triggers);
32         /*
33          * 6 秒钟后关闭
34          */
35         Thread.sleep(6_000);
36         scheduler.shutdown();
37     }
38 
39     @Data
40     public static class AcceptConcurrentJob implements Job {
41         private String name;
42 
43         @Override
44         public void execute(JobExecutionContext context) {
45             try {
46                 System.out.printf("i am %s \n", name);
47                 Thread.sleep(2_000);
48             } catch (InterruptedException e) {
49                 e.printStackTrace();
50             }
51         }
52     }
53 }

 

Please note that the top of the Details of  Identity, is set to  group0.detail, we created two the Trigger , the second trigger when it is created by specifying  Identity bind to the target Job, then submit this the Job , and two Trigger, can We see two triggers simultaneously execute method of starting a Job

 

Code above may be simplified to the following form:

 1 /**
 2  * @author pancc
 3  * @version 1.0
 4  */
 5 public class AcceptConcurrentDemo {
 6 
 7     public static void main(String[] args) throws SchedulerException, InterruptedException {
 8         JobDetail detail = JobBuilder.newJob(AcceptConcurrentJob.class)
 9                 .withIdentity("detail", "group0")
10                 .build();
11 
12 
13         Trigger trigger = TriggerBuilder.newTrigger()
14                 .withIdentity("ben_trigger")
15                 .usingJobData("name", "ben")
16                 .startNow()
17                 .build();
18 
19         Trigger triggers = TriggerBuilder.newTrigger()
20                 .withIdentity("mike_trigger")
21                 .usingJobData("name", "mike")
22                 .startNow()
23                 .build();
24 
25 
26         Scheduler scheduler = new StdSchedulerFactory().getScheduler();
27 
28         scheduler.start();
29         scheduler.scheduleJob(detail, Sets.newHashSet(trigger,triggers),true);
30         /*
31          * 6 秒钟后关闭
32          */
33         Thread.sleep(6_000);
34         scheduler.shutdown();
35     }
36 
37     @Data
38     public static class AcceptConcurrentJob implements Job {
39         private String name;
40 
41         @Override
42         public void execute(JobExecutionContext context) {
43             try {
44                 System.out.printf("i am %s \n", name);
45                 Thread.sleep(2_000);
46             } catch (InterruptedException e) {
47                 e.printStackTrace();
48             }
49         }
50     }
51 }

 

2.2 avoid concurrency

In order to avoid concurrency, we can use the annotation @ official of DisallowConcurrentExecution , by the increase in class this comment, we can observe a second trigger was queuing process:

 1 /**
 2  * @author pancc
 3  * @version 1.0
 4  */
 5 public class RejectConcurrentDemo {
 6 
 7     public static void main(String[] args) throws SchedulerException, InterruptedException {
 8         JobDetail detail = JobBuilder.newJob(RejectConcurrentJob.class)
 9                 .withIdentity("detail", "group0")
10                 .build();
11 
12 
13         Trigger trigger = TriggerBuilder.newTrigger()
14                 .withIdentity("ben_trigger")
15                 .usingJobData("name", "ben")
16                 .startNow()
17                 .build();
18 
19         Trigger triggers = TriggerBuilder.newTrigger()
20                 .withIdentity("mike_trigger")
21                 .usingJobData("name", "mike")
22                 .forJob("detail", "group0")
23                 .startNow()
24                 .build();
25 
26 
27         Scheduler scheduler = new StdSchedulerFactory().getScheduler();
28 
29         scheduler.start();
30         scheduler.scheduleJob(detail, trigger);
31         scheduler.scheduleJob(triggers);
32         /*
33          * 6 秒钟后关闭
34          */
35         Thread.sleep(6_000);
36         scheduler.shutdown();
37     }
38 
39 
40     @DisallowConcurrentExecution
41     @Data
42     public static class RejectConcurrentJob implements Job {
43         private String name;
44 
45         @Override
46         public void execute(JobExecutionContext context) {
47             try {
48                 System.out.printf("i am %s \n", name);
49                 Thread.sleep(2_000);
50             } catch (InterruptedException e) {
51                 e.printStackTrace();
52             }
53         }
54     }
55 }

 

 

Principle 3 Avoid concurrent exploration

Let's find  JobStore implementation class, in this case  RAMJobStore, point into the method org.quartz.simpl.RAMJobStore # acquireNextTriggers, you can see a piece of this method:

 

 By presence or absence of the Job class   DisallowConcurrentExecution annotation, if present, is rejected concurrently execute method. If you call the Trigger to be executed with a JobDetail objects, the current trigger into the waiting list.

 

After a Trigger current execution is completed, the waiting list to go back to re-add the Trigger trigger RAMJobStore held by, waiting for a next call happen.

Guess you like

Origin www.cnblogs.com/siweipancc/p/12596241.html