Я хочу создать программу, которая:
- Выполняет долгосрочную задачу, скажем, 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