Java: синхронизировать два запланированных потока на ScheduledExecutorService - PullRequest
0 голосов
/ 13 мая 2019

Я хочу создать программу, которая:

  • Выполняет долгосрочную задачу, скажем, 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 голосов
/ 13 мая 2019

Попробуйте синхронизировать в 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
...