• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 19391366536

15 Nov 2025 02:44PM UTC coverage: 84.12%. Remained the same
19391366536

push

github

TAKETODAY
:white_check_mark:

61484 of 78193 branches covered (78.63%)

Branch coverage included in aggregate %.

145228 of 167543 relevant lines covered (86.68%)

3.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.0
today-context/src/main/java/infra/scheduling/concurrent/ExecutorLifecycleDelegate.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.scheduling.concurrent;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.util.concurrent.ExecutorService;
23
import java.util.concurrent.locks.Condition;
24
import java.util.concurrent.locks.ReentrantLock;
25

26
import infra.context.SmartLifecycle;
27

28
/**
29
 * An internal delegate for common {@link ExecutorService} lifecycle management
30
 * with pause/resume support.
31
 *
32
 * @author Juergen Hoeller
33
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
34
 * @see ExecutorConfigurationSupport
35
 * @see SimpleAsyncTaskScheduler
36
 * @since 4.0
37
 */
38
final class ExecutorLifecycleDelegate implements SmartLifecycle {
39

40
  private final ExecutorService executor;
41

42
  private final ReentrantLock pauseLock = new ReentrantLock();
5✔
43

44
  private final Condition unpaused = this.pauseLock.newCondition();
5✔
45

46
  private volatile boolean paused;
47

48
  private volatile boolean shutdown;
49

50
  private int executingTaskCount = 0;
3✔
51

52
  @Nullable
53
  private Runnable stopCallback;
54

55
  public ExecutorLifecycleDelegate(ExecutorService executor) {
2✔
56
    this.executor = executor;
3✔
57
  }
1✔
58

59
  @Override
60
  public void start() {
61
    this.pauseLock.lock();
3✔
62
    try {
63
      this.paused = false;
3✔
64
      this.unpaused.signalAll();
3✔
65
    }
66
    finally {
67
      this.pauseLock.unlock();
3✔
68
    }
69
  }
1✔
70

71
  @Override
72
  public void stop() {
73
    this.pauseLock.lock();
3✔
74
    try {
75
      this.paused = true;
3✔
76
      this.stopCallback = null;
3✔
77
    }
78
    finally {
79
      this.pauseLock.unlock();
3✔
80
    }
81
  }
1✔
82

83
  @Override
84
  public void stop(Runnable callback) {
85
    this.pauseLock.lock();
3✔
86
    try {
87
      this.paused = true;
3✔
88
      if (this.executingTaskCount == 0) {
3!
89
        this.stopCallback = null;
3✔
90
        callback.run();
3✔
91
      }
92
      else {
93
        this.stopCallback = callback;
×
94
      }
95
    }
96
    finally {
97
      this.pauseLock.unlock();
3✔
98
    }
99
  }
1✔
100

101
  @Override
102
  public boolean isRunning() {
103
    return (!this.paused && !this.executor.isTerminated());
11✔
104
  }
105

106
  void markShutdown() {
107
    this.shutdown = true;
3✔
108
  }
1✔
109

110
  void beforeExecute(Thread thread) {
111
    this.pauseLock.lock();
3✔
112
    try {
113
      while (this.paused && !this.shutdown && !this.executor.isShutdown()) {
10!
114
        this.unpaused.await();
4✔
115
      }
116
    }
117
    catch (InterruptedException ex) {
×
118
      thread.interrupt();
×
119
    }
120
    finally {
121
      this.executingTaskCount++;
6✔
122
      this.pauseLock.unlock();
3✔
123
    }
124
  }
1✔
125

126
  void afterExecute() {
127
    this.pauseLock.lock();
3✔
128
    try {
129
      this.executingTaskCount--;
6✔
130
      if (this.executingTaskCount == 0) {
3✔
131
        Runnable callback = this.stopCallback;
3✔
132
        if (callback != null) {
2!
133
          callback.run();
×
134
          this.stopCallback = null;
×
135
        }
136
      }
137
    }
138
    finally {
139
      this.pauseLock.unlock();
3✔
140
    }
141
  }
1✔
142

143
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc