Java:在ScheduledExecutorService上同步两个调度的线程

时间:2019-05-13 12:33:24

标签: java multithreading thread-synchronization scheduledexecutorservice

我想要创建一个程序,该程序:

  • 做一个长期运行的任务,比如说ChildJob
  • 暂停主要任务ChildJob,并每隔几秒钟提交一次完成的工作

我想到了这段代码,该代码调度了两个线程,每隔几秒钟提交一次(当前提交部分是一个sop语句),并且还并行运行ChildJob。

我面临的问题是,我无法正确同步两个线程。

  • 在调用commit()时,ChildJob线程继续进行处理。如何使ChildJob线程等待?

我知道使process()方法同步不是一个选择,因为在这种情况下,commit()作业甚至无法运行。

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.Random;
import java.util.Date;


class Main {

    // Processing thread, commiting thread
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) {

        Main app = new Main();
        ChildJob workUnit = new ChildJob();

        Thread childJobThread = new Thread(new Runnable() 
        { 
            @Override
            public void run() 
            { 
                System.out.println("childJobThread: "+ Thread.currentThread().getName()+" Start. Time = " + new Date());
                try{ workUnit.process(); }
                catch(InterruptedException e){ e.printStackTrace(); } 
            } 
        }); 
        Thread committerThread = new Thread(new Runnable() 
        { 
            @Override
            public void run() 
            { 
                try{ workUnit.commit();  }
                catch(InterruptedException e){ e.printStackTrace(); } 
            } 
        }); 

        final ScheduledFuture<?> commitHandle = app.scheduler.scheduleAtFixedRate(committerThread, 1, 8, TimeUnit.SECONDS);
        final ScheduledFuture<?> jobHandle = app.scheduler.schedule(childJobThread, 0, TimeUnit.SECONDS);
        /*
        Makes the commitHandle run for 60 * 60 seconds, not needed, manually terminating currently.
        app.scheduler.schedule(new Runnable() {
                public void run() {
                    commitHandle.cancel(true);
                }
            }, 
            60 * 60, TimeUnit.SECONDS);*/
    }
}

class ChildJob {
    private int i = 0;

    public void process() throws InterruptedException 
    { 

         // synchronized(this) 
         // {   
            while(true) {
                System.out.println("ChildJob processing at: " + Thread.currentThread().getName() + " : " + new Date() + "----------: " + i++);
                Thread.sleep(1000);
            }
        //} 
    } 

    public void commit() throws InterruptedException 
    {   
        synchronized(this) 
        { 
            System.out.println("\ncommitterThread: " + Thread.currentThread().getName()+" Start. Time = " + new Date());
            // 3s sleep to check consistency from processing.
            Thread.sleep(3000);
            System.out.println("committerThread: " + Thread.currentThread().getName()+"     End. Time = " + new Date() + "\n");
        } 
    } 
}

现在的结果:

childJobThread: pool-1-thread-1 Start. Time = Mon May 13 17:51:31 IST 2019
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:31 IST 2019----------: 0

committerThread: pool-1-thread-2 Start. Time = Mon May 13 17:51:32 IST 2019
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:32 IST 2019----------: 1
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:33 IST 2019----------: 2
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:34 IST 2019----------: 3
committerThread: pool-1-thread-2     End. Time = Mon May 13 17:51:35 IST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:35 IST 2019----------: 4
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:36 IST 2019----------: 5
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:37 IST 2019----------: 6
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:38 IST 2019----------: 7
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:39 IST 2019----------: 8

committerThread: pool-1-thread-2 Start. Time = Mon May 13 17:51:40 IST 2019
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:40 IST 2019----------: 9
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:41 IST 2019----------: 10
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:43 IST 2019----------: 11
committerThread: pool-1-thread-2     End. Time = Mon May 13 17:51:43 IST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:44 IST 2019----------: 12
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:45 IST 2019----------: 13
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:46 IST 2019----------: 14
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:47 IST 2019----------: 15
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:48 IST 2019----------: 16

所需结果:

childJobThread: pool-1-thread-1 Start. Time = Mon May 13 17:51:31 IST 2019
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:31 IST 2019----------: 0

committerThread: pool-1-thread-2 Start. Time = Mon May 13 17:51:32 IST 2019
committerThread: pool-1-thread-2     End. Time = Mon May 13 17:51:35 IST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:35 IST 2019----------: 1
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:36 IST 2019----------: 2
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:37 IST 2019----------: 3
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:38 IST 2019----------: 4
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:39 IST 2019----------: 5

committerThread: pool-1-thread-2 Start. Time = Mon May 13 17:51:40 IST 2019
committerThread: pool-1-thread-2     End. Time = Mon May 13 17:51:43 IST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:44 IST 2019----------: 6
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:45 IST 2019----------: 7
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:46 IST 2019----------: 8
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:47 IST 2019----------: 9
ChildJob processing at: pool-1-thread-1 : Mon May 13 17:51:48 IST 2019----------: 10

1 个答案:

答案 0 :(得分:-3)

尝试在while中进行同步,说:


while(true) {
  synchronized(this) 
    {   
      System.out.println("ChildJob processing at: " + Thread.currentThread().getName() + " : " + new Date() + "----------: " + i++);
      Thread.sleep(1000);
    }
  } 
}

想法是,commit应该有机会闯入job

示例输出

childJobThread: pool-1-thread-1 Start. Time = Mon May 13 20:42:46 CST 2019
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:46 CST 2019----------: 0
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:47 CST 2019----------: 1
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:48 CST 2019----------: 2
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:49 CST 2019----------: 3
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:50 CST 2019----------: 4
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:52 CST 2019----------: 5
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:53 CST 2019----------: 6

committerThread: pool-1-thread-2 Start. Time = Mon May 13 20:42:54 CST 2019
committerThread: pool-1-thread-2     End. Time = Mon May 13 20:42:57 CST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:57 CST 2019----------: 7
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:58 CST 2019----------: 8
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:42:59 CST 2019----------: 9
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:00 CST 2019----------: 10
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:01 CST 2019----------: 11

committerThread: pool-1-thread-2 Start. Time = Mon May 13 20:43:02 CST 2019
committerThread: pool-1-thread-2     End. Time = Mon May 13 20:43:05 CST 2019

ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:05 CST 2019----------: 12
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:06 CST 2019----------: 13
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:07 CST 2019----------: 14
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:08 CST 2019----------: 15
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:09 CST 2019----------: 16
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:10 CST 2019----------: 17
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:11 CST 2019----------: 18
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:12 CST 2019----------: 19
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:13 CST 2019----------: 20
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:14 CST 2019----------: 21
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:15 CST 2019----------: 22
ChildJob processing at: pool-1-thread-1 : Mon May 13 20:43:16 CST 2019----------: 23