HBASE-24163 MOB compactor implementations should use format specifiers when calling...
[hbase.git] / hbase-common / src / main / java / org / apache / hadoop / hbase / util / Sleeper.java
blob54acceffb3c73ad84659cb772cd317549fee1d61
1 /**
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 package org.apache.hadoop.hbase.util;
21 import org.apache.hadoop.hbase.Stoppable;
22 import org.apache.yetus.audience.InterfaceAudience;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 /**
27 * Sleeper for current thread.
28 * Sleeps for passed period. Also checks passed boolean and if interrupted,
29 * will return if the flag is set (rather than go back to sleep until its
30 * sleep time is up).
32 @InterfaceAudience.Private
33 public class Sleeper {
34 private static final Logger LOG = LoggerFactory.getLogger(Sleeper.class);
35 private final int period;
36 private final Stoppable stopper;
37 private static final long MINIMAL_DELTA_FOR_LOGGING = 10000;
39 private final Object sleepLock = new Object();
40 private boolean triggerWake = false;
42 /**
43 * @param sleep sleep time in milliseconds
44 * @param stopper When {@link Stoppable#isStopped()} is true, this thread will
45 * cleanup and exit cleanly.
47 public Sleeper(final int sleep, final Stoppable stopper) {
48 this.period = sleep;
49 this.stopper = stopper;
52 /**
53 * If currently asleep, stops sleeping; if not asleep, will skip the next
54 * sleep cycle.
56 public void skipSleepCycle() {
57 synchronized (sleepLock) {
58 triggerWake = true;
59 sleepLock.notifyAll();
63 /**
64 * Sleep for period.
66 public void sleep() {
67 sleep(this.period);
70 public void sleep(long sleepTime) {
71 if (this.stopper.isStopped()) {
72 return;
74 long now = System.currentTimeMillis();
75 long currentSleepTime = sleepTime;
76 while (currentSleepTime > 0) {
77 long woke = -1;
78 try {
79 synchronized (sleepLock) {
80 if (triggerWake) {
81 break;
84 sleepLock.wait(currentSleepTime);
86 woke = System.currentTimeMillis();
87 long slept = woke - now;
88 if (slept - this.period > MINIMAL_DELTA_FOR_LOGGING) {
89 LOG.warn("We slept {}ms instead of {}ms, this is likely due to a long " +
90 "garbage collecting pause and it's usually bad, see " +
91 "http://hbase.apache.org/book.html#trouble.rs.runtime.zkexpired", slept, this.period);
93 } catch(InterruptedException iex) {
94 // We we interrupted because we're meant to stop? If not, just
95 // continue ignoring the interruption
96 if (this.stopper.isStopped()) {
97 return;
100 // Recalculate waitTime.
101 woke = (woke == -1)? System.currentTimeMillis(): woke;
102 currentSleepTime = this.period - (woke - now);
104 synchronized(sleepLock) {
105 triggerWake = false;
110 * @return the sleep period in milliseconds
112 public final int getPeriod() {
113 return period;