Java Thread.sleep() Method: Syntax and Examples
Learn Java Thread.sleep() syntax, overloads, interruption handling, timing limits, and why sleeping does not release locks or provide synchronization.
Thread.sleep() pauses the thread that calls it for a requested duration. It is a static method, so it does not pause every thread in your application. The thread may resume later than requested because timers and scheduling affect when it runs again. Sleeping also does not release monitors, and it does not make shared data visible between threads.
Use sleep for simple pacing or a deliberate timed pause. Handle InterruptedException as a cancellation request, and use synchronization or a condition-based mechanism when your code needs to wait for another thread or for shared state to change.
1. Basic syntax and a runnable example
The method is static on java.lang.Thread, which is imported automatically. This example compiles and runs on Java 8 and later:
public class SleepExample {
public static void main(String[] args) {
try {
for (int i = 1; i <= 3; i++) {
System.out.println("Step " + i);
Thread.sleep(1_000); // request a one-second pause
}
} catch (InterruptedException e) {
// Preserve the cancellation signal for code higher in the call stack.
Thread.currentThread().interrupt();
return;
}
}
}
Save it as SleepExample.java, compile with javac SleepExample.java, and run it with java SleepExample. The pause occurs after each printed step, including the last one.
2. Overloads, units, and Java version support
| Call | Requested duration | Version notes | Argument behavior |
|---|---|---|---|
Thread.sleep(long millis) |
Milliseconds | Use this for broad compatibility, including older Java versions. | Negative milliseconds throw IllegalArgumentException. |
Thread.sleep(long millis, int nanos) |
Milliseconds plus additional nanoseconds | Available in older Java versions. | millis must be nonnegative; nanos must be between 0 and 999,999 inclusive. Invalid values throw IllegalArgumentException. |
Thread.sleep(Duration duration) |
A java.time.Duration |
Available since Java 19. | A negative duration is a no-op. A null duration is not a valid argument. |
All overloads can throw InterruptedException. The current Java API documents these signatures and their argument behavior in the Thread API reference.
Millisecond and nanosecond form
try {
Thread.sleep(250, 500_000); // request 250 ms plus 500,000 ns
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
The second argument is an additional amount below one millisecond; it is not a total nanosecond count. Supplying 1_000_000 as nanos is invalid. Even a valid nanosecond argument does not guarantee nanosecond wake-up precision.
Duration form (Java 19 and later)
import java.time.Duration;
class DurationSleepExample {
static void pause() throws InterruptedException {
Thread.sleep(Duration.ofMillis(250));
}
}
Duration can make units clear at the call site. If your project targets Java 8 through 18, use one of the numeric overloads instead.
3. Handle interruption as cancellation
Interruption is a cooperative signal that a thread should stop or cancel its current work. If a thread is interrupted while sleeping, sleep throws InterruptedException and clears the thread’s interrupted status. Do not silently ignore the exception and continue as though nothing happened.
If your method can propagate the exception, declare it and let the caller decide how to stop:
static void waitBeforeRetry() throws InterruptedException {
Thread.sleep(500);
}
If the method cannot propagate it, restore the status before returning or completing cancellation handling:
static boolean waitBeforeRetry() {
try {
Thread.sleep(500);
return true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
Restoring the status matters because catching InterruptedException clears it. Higher-level code can then observe the cancellation request with Thread.currentThread().isInterrupted().
4. What sleep does and does not guarantee
The calling thread pauses; the application does not
Thread.sleep is static and pauses the currently executing thread. Other runnable threads can continue. Calling someThread.sleep(1000) is legal Java syntax, but misleading: the receiver is ignored. Prefer Thread.sleep(1000) to make the behavior clear.
The requested duration is not an exact wake-up time
The Java API says sleep is subject to the precision and accuracy of system timers and schedulers. After the requested interval, the thread becomes eligible to run; scheduling delays can make it resume later. Do not use sleep to meet a precise deadline, measure elapsed time, or guarantee a fixed-rate schedule. The Oracle sleep tutorial also describes it as a pausing and pacing mechanism; that tutorial targets JDK 8 and warns that it may not reflect later releases.
Sleep does not release a monitor
If a thread calls sleep inside a synchronized block or method, it keeps ownership of the monitor while sleeping. Another thread that needs the same monitor may remain blocked until the sleeper exits the synchronized region.
synchronized (lock) {
// Avoid sleeping here if another thread needs lock to make progress.
Thread.sleep(1_000);
}
Oracle’s API states that the sleeping thread does not lose ownership of monitors. If you need to wait for a condition while releasing a monitor, Object.wait() is a different mechanism and must be used while owning that object’s monitor.
Sleep does not make shared state safe or visible
Thread.sleep has no synchronization semantics. A sleep call does not flush writes or force another thread to reload a shared value. The Java Language Specification explicitly notes that a loop reading an ordinary, non-volatile flag and then sleeping can keep seeing a cached value. Use an appropriate coordination mechanism such as a volatile field, a lock, or a higher-level concurrency utility. See JLS §17, Threads and Locks.
5. Choose the right waiting mechanism
| Need | Use | Why |
|---|---|---|
| Pause this thread for pacing | Thread.sleep |
Waits for elapsed time; does not release owned monitors. |
| Wait until another thread finishes | Thread.join |
Waits for a particular thread’s termination, optionally with a timeout. |
| Wait for a condition while coordinating through a monitor | Object.wait inside a condition-checking loop, with notification |
Releases the object’s monitor while waiting and reacquires it before returning. |
| Schedule delayed or repeated work | ScheduledExecutorService |
Separates task scheduling from manually occupying a thread in a sleep loop. |
Choose based on what ends the wait: elapsed time, another thread’s completion, a condition becoming true, or a scheduled task becoming due. A sleep-based polling loop can add response delay and wake-ups; it is not a substitute for condition signaling.
6. Common errors and fixes
| Symptom | Cause | Fix |
|---|---|---|
Unhandled exception type InterruptedException |
sleep is interruptible and the checked exception is neither caught nor declared. |
Add throws InterruptedException when callers can handle cancellation, or catch it and restore the interrupt status. |
IllegalArgumentException |
A numeric duration is negative, or the nanosecond argument is outside 0..999999. |
Validate inputs, clamp or reject invalid values according to the method’s contract, and use the right units. |
| Another thread appears stuck while this thread sleeps | The sleeping thread still owns a monitor needed by the other thread. | Move the timed pause outside the synchronized region, or use condition-based coordination designed to release the monitor. |
| A flag change is not noticed after sleeping | Sleep does not provide memory visibility; a plain shared field may be read repeatedly without synchronization. | Use volatile, a lock, or an appropriate concurrency primitive. |
| The thread wakes later than requested | Timer precision, OS scheduling, and processor availability affect when it runs again. | Treat the duration as a minimum requested pause, not a deadline. Use a scheduling or timing design that matches the required tolerance. |
| Code sleeps but another thread does not | Only the current caller is paused; the method is not an instance method on the thread variable. | Use Thread.sleep for the current thread. Use join or another coordination primitive when waiting on another thread. |
7. Performance, reliability, and cost notes
- CPU: A sleeping thread is not continuously running application code during the pause, so sleep can yield processor time. It still occupies a thread and retains any monitors it owns.
- Latency: Wake-up can occur later than requested. A loop that sleeps between checks also delays noticing a change until a later check.
- Reliability: Interruption can end a sleep early by throwing. Propagate or preserve that signal so shutdown and cancellation work predictably.
- Timing: Do not assume the requested delay equals measured elapsed time or use it as a precise clock. For elapsed-time measurement, use a monotonic time source such as
System.nanoTime(); for delayed execution, use a scheduler. - Cost:
Thread.sleepis part of the Java standard library and has no per-call service charge. Operational costs depend on the threads and application resources your program keeps occupied.
8. Or skip the browser setup
If your Java work also needs website screenshots, ScreenshotNeo provides a screenshot API and MCP server. One GET request can return an image or PDF. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners, popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed. Responses include
X-Page-VerdictandX-Billedheaders. - An MCP server lets AI agents use
take_screenshot,get_page_info, andcapture_pdf. - 1,000 screenshots per month are free with no card. Paid plans start at $5 for 3,000 screenshots.
Create a free ScreenshotNeo account to start with 1,000 screenshots a month and no card.
9. FAQ
Is Thread.sleep(0) the same as yielding?
It requests a zero-length sleep; it is not a reliable way to force another thread to run. Thread.yield() is a separate scheduler hint, and neither method provides synchronization.
Can I call sleep without writing Thread.?
Only if you statically import the method, for example import static java.lang.Thread.sleep;. Most code uses Thread.sleep(...) because it makes the static call clear.
Does sleep stop a thread permanently?
No. It pauses the current thread for a requested interval or until interruption, then the thread may continue when scheduled.
Can sleep be used in a constructor or static method?
Yes. It is a static method and can be called from any context, though a pause during construction or class initialization can delay other work unexpectedly.


