xuxueli / xxl-job

A distributed task scheduling framework.(分布式任务调度平台XXL-JOB)
http://www.xuxueli.com/xxl-job/
GNU General Public License v3.0
27.51k stars 10.89k forks source link

执行器创建并注册线程的逻辑有线程安全问题 #2375

Open hfc1994 opened 3 years ago

hfc1994 commented 3 years ago

Please answer some questions before submitting your issue. Thanks!

Which version of XXL-JOB do you using?

2.3.1-SNAPSHOT

Expected behavior

同一个id的job在并发执行时只创建一次线程

Actual behavior

同一个id的job在并发执行时有概率创建多次线程

Steps to reproduce the behavior

可以很简单的复现问题,在xxl-job-executor-samples/xxl-job-executor-sample-sprintboot的XxlJobExecutorApplication.java里面添加如下代码

        @Component
    public class test implements ApplicationRunner {

        @Override
        public void run(ApplicationArguments args) throws Exception {
            ExecutorBiz executorBiz = new ExecutorBizImpl();
            Thread[] ts = new Thread[3];
            for (int i=0; i<3; i++) {
                final int j = i;
                Thread t = new Thread(() -> {
                    TriggerParam triggerParam = new TriggerParam();
                    triggerParam.setJobId(2);    // 相同的job id
                    triggerParam.setExecutorHandler("demoJobHandler");
                    triggerParam.setExecutorParams(null);
                    triggerParam.setExecutorBlockStrategy(ExecutorBlockStrategyEnum.SERIAL_EXECUTION.getTitle());
                    triggerParam.setExecutorTimeout(0);
                    triggerParam.setLogId(55+j);    // 为了方便测试,复用之前的job执行信息
                    triggerParam.setLogDateTime(1618390300000L);
                    triggerParam.setGlueType(GlueTypeEnum.BEAN.name());
                    triggerParam.setGlueSource(null);
                    triggerParam.setGlueUpdatetime(1617706690000L);
                    triggerParam.setBroadcastIndex(0);
                    triggerParam.setBroadcastTotal(0);

                    executorBiz.run(triggerParam);
                });
                ts[i] = t;
            }

            for (Thread t : ts) {
                t.start();
            }
        }
    }

然后就可以在日志中看到注册了3次线程,其中前面两个线程会被中止掉,实际对应的job也没执行完

15:31:34.193 logback [Thread-13] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:2, handler:com.xxl.job.core.handler.impl.MethodJobHandler@6e03db1f[class com.xxl.job.executor.service.jobhandler.SampleXxlJob#demoJobHandler]
15:31:34.193 logback [Thread-14] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:2, handler:com.xxl.job.core.handler.impl.MethodJobHandler@6e03db1f[class com.xxl.job.executor.service.jobhandler.SampleXxlJob#demoJobHandler]
15:31:34.193 logback [Thread-15] INFO  c.x.job.core.executor.XxlJobExecutor - >>>>>>>>>>> xxl-job regist JobThread success, jobId:2, handler:com.xxl.job.core.handler.impl.MethodJobHandler@6e03db1f[class com.xxl.job.executor.service.jobhandler.SampleXxlJob#demoJobHandler]
15:31:34.198 logback [Thread-17] INFO  com.xxl.job.core.thread.JobThread - >>>>>>>>>>> xxl-job JobThread stoped, hashCode:Thread[Thread-17,5,main]
15:31:34.202 logback [Thread-18] INFO  com.xxl.job.core.thread.JobThread - >>>>>>>>>>> xxl-job JobThread stoped, hashCode:Thread[Thread-18,5,main]

Other information

Greatom commented 9 months ago

同问,不知道这个功能添加了吗?