Deadlock, Livelock, and Thread Starvation in Java Concurrency

This article explains Java concurrency issues such as deadlock, livelock, and thread starvation, demonstrates deadlock examples, discusses prevention techniques like timeouts and lock ordering, and provides an overview of the java.util.concurrent package including executors, locks, semaphores, latches, barriers, and concurrent collections.

FunTester
FunTester
FunTester
Deadlock, Livelock, and Thread Starvation in Java Concurrency

Continuation of Java concurrency programming basics.

Deadlock, Livelock and Thread Starvation

Deadlock

Deadlock occurs when two or more threads are waiting for each other to release resources, causing a standstill. The following example shows two threads each holding one lock and waiting for the other.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px">  <br/><span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">final</span> Object lock1 = <span style="color: #c678dd; line-height: 26px">new</span> Object()  <br/>  <br/><span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">final</span> Object lock2 = <span style="color: #c678dd; line-height: 26px">new</span> Object()  <br/>  <br/><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">main</span><span style="line-height: 26px">(String[] args)</span> </span>{  <br/>    Thread thread1 = <span style="color: #c678dd; line-height: 26px">new</span> Thread(() -> {  <br/>        <span style="color: #c678dd; line-height: 26px">synchronized</span> (lock1) {  <br/>            println(<span style="color: #98c379; line-height: 26px">"线程1持有锁1"</span>)  <br/>            <span style="color: #c678dd; line-height: 26px">try</span> {  <br/>                Thread.sleep(<span style="color: #d19a66; line-height: 26px">100</span>)  <br/>            } <span style="color: #c678dd; line-height: 26px">catch</span> (InterruptedException e) {  <br/>            }  <br/>            println(<span style="color: #98c379; line-height: 26px">"线程1等待获取锁2"</span>)  <br/>            <span style="color: #c678dd; line-height: 26px">synchronized</span> (lock2) {  <br/>                println(<span style="color: #98c379; line-height: 26px">"线程池持有锁2"</span>)  <br/>            }  <br/>        }  <br/>    })  <br/>  <br/>    Thread thread2 = <span style="color: #c678dd; line-height: 26px">new</span> Thread(() -> {  <br/>        <span style="color: #c678dd; line-height: 26px">synchronized</span> (lock2) {  <br/>            println(<span style="color: #98c379; line-height: 26px">"线程2持有锁2"</span>)  <br/>            <span style="color: #c678dd; line-height: 26px">try</span> {  <br/>                Thread.sleep(<span style="color: #d19a66; line-height: 26px">100</span>)  <br/>            } <span style="color: #c678dd; line-height: 26px">catch</span> (InterruptedException e) {  <br/>            }  <br/>            println(<span style="color: #98c379; line-height: 26px">"线程2等待获取锁1"</span>)  <br/>            <span style="color: #c678dd; line-height: 26px">synchronized</span> (lock1) {  <br/>                println(<span style="color: #98c379; line-height: 26px">"线程2持有锁1"</span>)  <br/>            }  <br/>        }  <br/>    })  <br/>    thread1.start()  <br/>    thread2.start()  <br/>}<br/></code>

Both threads now wait for each other's lock, causing the program to hang indefinitely. A thread dump shows each thread in a BLOCKED state.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menke, monospace; font-size: 12px"><span style="color: #98c379; line-height: 26px">"Thread-1"</span> <span style="color: #5c6370; font-style: italic; line-height: 26px">#28 [25091] prio=5 os_prio=31 cpu=13.87ms elapsed=24.40s tid=0x00007fceea86d000 nid=25091 waiting for monitor entry  [0x0000700010268000]</span><br/>   java.lang.Thread.State: BLOCKED (on object monitor)<br/> at com.funtest.temp.ImmutablePerson<span style="color: #d19a66; line-height: 26px">$_main_closure2</span>.doCall(ImmutablePerson.groovy:35)<br/> - waiting to lock <0x000000070e355c90> (a java.lang.Object)<br/> - locked <0x000000070e32b478> (a java.lang.Object)<br/></code>

Overcoming Deadlock

Common techniques to avoid or resolve deadlock include using lock acquisition timeouts (e.g., ReentrantLock with java.util.concurrent.locks), establishing a consistent lock order across threads, employing resource‑allocation‑graph algorithms, and designing code with higher‑level abstractions such as java.util.concurrent utilities.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px"><br/>    <span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">final</span> Lock lock1 = <span style="color: #c678dd; line-height: 26px">new</span> ReentrantLock()<br/>    <span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">final</span> Lock lock2 = <span style="color: #c678dd; line-height: 26px">new</span> ReentrantLock()<br/><br/>    <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">main</span><span style="line-height: 26px">(String[] args)</span> </span>{<br/>        Runnable acquireLocks = () -> {<br/>            lock1.lock()<br/>            <span style="color: #c678dd; line-height: 26px">try</span> {<br/>                println(Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">": 持有锁1"</span>)<br/>                <span style="color: #c678dd; line-height: 26px">try</span> {<br/>                    Thread.sleep(<span style="color: #d19a66; line-height: 26px">100</span>)<br/>                } <span style="color: #c678dd; line-height: 26px">catch</span> (InterruptedException e) {<br/>                }<br/>                println(Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">": 等待获取锁2"</span>)<br/>                <br/>                <span style="color: #c678dd; line-height: 26px">boolean</span> acquiredLock2 = lock2.tryLock(<span style="color: #d19a66; line-height: 26px">500</span>, TimeUnit.MILLISECONDS)<br/>                <span style="color: #c678dd; line-height: 26px">if</span> (acquiredLock2) {<br/>                    <span style="color: #c678dd; line-height: 26px">try</span> {<br/>                        println(Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">": 获取锁2"</span>)<br/>                    } <span style="color: #c678dd; line-height: 26px">finally</span> {<br/>                        lock2.unlock()<br/>                    }<br/>                } <span style="color: #c678dd; line-height: 26px">else</span> {<br/>                    println(Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">": 获取锁2超时"</span>)<br/>                }<br/>            } <span style="color: #c678dd; line-height: 26px">finally</span> {<br/>                lock1.unlock()<br/>            }<br/>        }<br/>        Thread thread1 = <span style="color: #c678dd; line-height: 26px">new</span> Thread(acquireLocks)<br/>        Thread thread2 = <span style="color: #c678dd; line-height: 26px">new</span> Thread(acquireLocks)<br/>        thread1.start()<br/>        thread2.start()<br/>    }<br/>    <br/></code>

Livelock

Livelock is a special form of deadlock where threads keep responding to each other without making progress. The following example models two diners repeatedly yielding a shared spoon to each other, preventing either from eating.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">class</span> <span style="color: #e6c07b; line-height: 26px">LivelockExample</span> </span>{  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 勺子类  </span><br/>    <span style="color: #c678dd; line-height: 26px">static</span> <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">class</span> <span style="color: #e6c07b; line-height: 26px">Spoon</span> </span>{  <br/>        <span style="color: #c678dd; line-height: 26px">private</span> Diner owner;  <br/>  <br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #61aeee; line-height: 26px">Spoon</span><span style="line-height: 26px">(Diner owner)</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">this</span>.owner = owner;  <br/>        }  <br/>  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 使用勺子  </span><br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #c678dd; line-height: 26px">synchronized</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">use</span><span style="line-height: 26px">()</span> </span>{  <br/>            System.out.println(owner.getName() + <span style="color: #98c379; line-height: 26px">"使用了勺子"</span>);  <br/>        }  <br/>  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 设置勺子的所有者  </span><br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #c678dd; line-height: 26px">synchronized</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">setOwner</span><span style="line-height: 26px">(Diner owner)</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">this</span>.owner = owner;  <br/>        }  <br/>    }  <br/>  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 就餐者类  </span><br/>    <span style="color: #c678dd; line-height: 26px">static</span> <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">class</span> <span style="color: #e6c07b; line-height: 26px">Diner</span> </span>{  <br/>        <span style="color: #c678dd; line-height: 26px">private</span> String name;  <br/>        <span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">boolean</span> isHungry;  <br/>  <br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #61aeee; line-height: 26px">Diner</span><span style="line-height: 26px">(String name)</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">this</span>.name = name;  <br/>            <span style="color: #c678dd; line-height: 26px">this</span>.isHungry = <span style="color: #c678dd; line-height: 26px">true</span>;  <br/>        }  <br/>  <br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> String <span style="color: #61aeee; line-height: 26px">getName</span><span style="line-height: 26px">()</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">return</span> name;  <br/>        }  <br/>  <br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #c678dd; line-height: 26px">boolean</span> <span style="color: #61aeee; line-height: 26px">isHungry</span><span style="line-height: 26px">()</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">return</span> isHungry;  <br/>        }  <br/>  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 与配偶一起进餐  </span><br/>        <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">eatWith</span><span style="line-height: 26px">(Spoon spoon, Diner spouse)</span> </span>{  <br/>            <span style="color: #c678dd; line-height: 26px">while</span> (isHungry) {  <br/>                <span style="color: #5c6370; font-style: italic; line-height: 26px">// 如果勺子不属于当前就餐者,继续等待  </span><br/>                <span style="color: #c678dd; line-height: 26px">if</span> (spoon.owner != <span style="color: #c678dd; line-height: 26px">this</span>) {  <br/>                    <span style="color: #c678dd; line-height: 26px">continue</span>;  <br/>                }  <br/>  <br/>                <span style="color: #5c6370; font-style: italic; line-height: 26px">// 如果配偶也在等待就餐,让配偶先吃  </span><br/>                <span style="color: #c678dd; line-height: 26px">if</span> (spouse.isHungry()) {  <br/>                    System.out.println(getName() + <span style="color: #98c379; line-height: 26px">": 亲爱的 "</span> + spouse.getName() + <span style="color: #98c379; line-height: 26px">",你先吃吧。"</span>);  <br/>                    spoon.setOwner(spouse);  <br/>                    <span style="color: #c678dd; line-height: 26px">continue</span>;  <br/>                }  <br/>  <br/>                <span style="color: #5c6370; font-style: italic; line-height: 26px">// 否则就餐者使用勺子,标记自己不再饥饿,并将勺子所有权交给配偶  </span><br/>                spoon.use();  <br/>                isHungry = <span style="color: #c678dd; line-height: 26px">false</span>;  <br/>                System.out.println(getName() + <span style="color: #98c379; line-height: 26px">": 我吃完了,你可以吃了 "</span> + spouse.getName() + <span style="color: #98c379; line-height: 26px">"."</span>);  <br/>                spoon.setOwner(spouse);  <br/>            }  <br/>        }  <br/>    }  <br/>  <br/>    <span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">public</span> <span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">main</span><span style="line-height: 26px">(String[] args)</span> </span>{  <br/>        <span style="color: #c678dd; line-height: 26px">final</span> Diner husband = <span style="color: #c678dd; line-height: 26px">new</span> Diner(<span style="color: #98c379; line-height: 26px">"丈夫"</span>);  <br/>        <span style="color: #c678dd; line-height: 26px">final</span> Diner wife = <span style="color: #c678dd; line-height: 26px">new</span> Diner(<span style="color: #98c379; line-height: 26px">"妻子"</span>);  <br/>  <br/>        <span style="color: #c678dd; line-height: 26px">final</span> Spoon sharedSpoon = <span style="color: #c678dd; line-height: 26px">new</span> Spoon(husband);  <br/>  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 创建丈夫线程,与妻子一起进餐  </span><br/>        Thread husbandThread = <span style="color: #c678dd; line-height: 26px">new</span> Thread(() -> husband.eatWith(sharedSpoon, wife));  <br/>        husbandThread.start();  <br/>  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 创建妻子线程,与丈夫一起进餐  </span><br/>        Thread wifeThread = <span style="color: #c678dd; line-height: 26px">new</span> Thread(() -> wife.eatWith(sharedSpoon, husband));  <br/>        wifeThread.start();  <br/>    }  <br/>}<br/></code>

Thread Starvation

Thread starvation refers to situations where some threads are continuously blocked because they cannot obtain needed resources, often caused by high contention, priority inversion, or unfair scheduling, leading to performance degradation.

java.util.concurrent Package

The java.util.concurrent package provides a large collection of classes and interfaces that simplify concurrent and multithreaded programming by offering high‑level abstractions for thread management, synchronization, and concurrent data structures.

Executor and ExecutorService

Executor

is an interface representing an object that can execute tasks asynchronously. ExecutorService extends it, adding lifecycle management and task‑submission methods, and serves as the core interface for thread pools.

Common implementations include ThreadPoolExecutor, ScheduledThreadPoolExecutor, ForkJoinPool, WorkStealingPool, SingleThreadExecutor, FixedThreadPool, CachedThreadPool, and others. The table below summarizes each implementation.

Executor Service Implementation

Description ThreadPoolExecutor A versatile and configurable executor service allowing custom core and maximum thread counts. ScheduledThreadPoolExecutor Extends ThreadPoolExecutor to schedule tasks at specific times or intervals. ForkJoinPool Specialized ExecutorService for parallel execution, especially suited for recursive tasks. WorkStealingPool Implementation of ForkJoinPool that uses a work‑stealing algorithm. SingleThreadExecutor Creates an executor with a single worker thread for sequential task execution. FixedThreadPool Fixed‑size thread pool managing a predetermined number of worker threads. CachedThreadPool Thread pool that dynamically adjusts the number of threads based on demand. SingleThreadScheduledExecutor Single‑threaded scheduler for fixed‑rate or fixed‑delay task execution. FixedScheduledThreadPool Combines a fixed‑size thread pool with scheduling capabilities.

Task types include Runnable (no return value) and Callable<V> (returns a result). Future<V> represents the result of an asynchronous computation.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">main</span><span style="line-height: 26px">(String[] args)</span> </span>{  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 创建一个固定大小为2的线程池  </span><br/>    ExecutorService executorService = Executors.newFixedThreadPool(<span style="color: #d19a66; line-height: 26px">2</span>)  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// Runnable接口的run()方法没有返回值,所以使用Runnable接口的任务不会返回结果  </span><br/>    Runnable runnableTask = () -> {  <br/>        String threadName = Thread.currentThread().getName()  <br/>        println(<span style="color: #98c379; line-height: 26px">"执行线程 "</span> + threadName)  <br/>    }  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// Callable接口的call()方法返回一个结果,所以使用Callable接口的任务会返回结果  </span><br/>    List<Callable<String>> callableTasks = List.of(  <br/>            () -> {  <br/>                String threadName = Thread.currentThread().getName()  <br/>                <span style="color: #c678dd; line-height: 26px">return</span> <span style="color: #98c379; line-height: 26px">"任务执行线程:   "</span> + threadName  <br/>            },  <br/>            () -> {  <br/>                String threadName = Thread.currentThread().getName()  <br/>                <span style="color: #c678dd; line-height: 26px">return</span> <span style="color: #98c379; line-height: 26px">"任务执行线程:   "</span> + threadName  <br/>            }  <br/>    )  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 提交Runnable任务给线程池执行  </span><br/>    executorService.submit(runnableTask)  <br/>    <span style="color: #c678dd; line-height: 26px">try</span> {  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 提交Callable任务给线程池执行,invokeAll()方法等待所有任务完成  </span><br/>        List<Future<String>> futures = executorService.invokeAll(callableTasks)  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 获取所有任务的结果  </span><br/>        <span style="color: #c678dd; line-height: 26px">for</span> (Future<String> future : futures) {  <br/>            println(future.get())  <br/>        }  <br/>        <span style="color: #5c6370; font-style: italic; line-height: 26px">// 使用invokeAny提交一组Callable任务并等待第一个完成的任务  </span><br/>        String firstResult = executorService.invokeAny(callableTasks)  <br/>        println(<span style="color: #98c379; line-height: 26px">"第一个任务完成结果: "</span> + firstResult)  <br/>    } <span style="color: #c678dd; line-height: 26px">catch</span> (Exception e) {  <br/>        e.printStackTrace()  <br/>    }  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 关闭线程池  </span><br/>    executorService.shutdown()  <br/>}<br/></code>

Console output demonstrates task execution order and thread names.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px">执行线程 pool-1-thread-1<br/>任务执行线程:   pool-1-thread-2<br/>任务执行线程:   pool-1-thread-2<br/>第一个任务完成结果: 任务执行线程:   pool-1-thread-2<br/></code>

Semaphore

Semaphore manages concurrent access to a limited number of permits. It provides acquire() to obtain a permit (blocking if none are available) and release() to return a permit.

CountDownLatch

CountDownLatch allows one or more threads to wait until a set of operations performed by other threads completes. Threads call countDown() to decrement the counter and await() to block until the counter reaches zero.

CyclicBarrier

CyclicBarrier enables a group of threads to wait at a common barrier point until all have arrived, then optionally executes a barrier action before resetting for reuse.

Concurrent Collections

Concurrent collection classes such as ConcurrentHashMap, BlockingQueue (including LinkedBlockingQueue, DelayQueue, PriorityBlockingQueue, SynchronousQueue), ConcurrentLinkedQueue, CopyOnWriteArrayList, and others provide thread‑safe data structures for high‑concurrency scenarios.

Atomic Classes

The java.util.concurrent.atomic package offers atomic primitives like AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference, and array variants to perform lock‑free thread‑safe operations.

Locks

Beyond synchronized, the java.util.concurrent.locks package provides Lock and ReadWriteLock interfaces with implementations such as ReentrantLock and ReentrantReadWriteLock for more flexible locking strategies.

<code style="padding: 16px; color: #abb2bf; display: -webkit-box; font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace; font-size: 12px"><span style="color: #c678dd; line-height: 26px">private</span> <span style="color: #c678dd; line-height: 26px">static</span> ReentrantLock lock = <span style="color: #c678dd; line-height: 26px">new</span> ReentrantLock()  <br/>  <br/><span style="line-height: 26px"><span style="color: #c678dd; line-height: 26px">static</span> <span style="color: #c678dd; line-height: 26px">void</span> <span style="color: #61aeee; line-height: 26px">main</span><span style="line-height: 26px">(String[] args)</span> </span>{  <br/>    Runnable task = () -> {  <br/>        lock.lock()<span style="color: #5c6370; font-style: italic; line-height: 26px">// 获取锁  </span><br/>        <span style="color: #c678dd; line-height: 26px">try</span> {  <br/>            System.out.println(<span style="color: #98c379; line-height: 26px">"Thread "</span> + Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">" 获取到了锁"</span>)  <br/>            <span style="color: #5c6370; font-style: italic; line-height: 26px">// 模拟业务处理  </span><br/>            Thread.sleep(<span style="color: #d19a66; line-height: 26px">1000</span>)  <br/>        } <span style="color: #c678dd; line-height: 26px">catch</span> (InterruptedException e) {  <br/>            Thread.currentThread().interrupt()  <br/>        } <span style="color: #c678dd; line-height: 26px">finally</span> {  <br/>            lock.unlock() <span style="color: #5c6370; font-style: italic; line-height: 26px">// 释放锁  </span><br/>            System.out.println(<span style="color: #98c379; line-height: 26px">"Thread "</span> + Thread.currentThread().getName() + <span style="color: #98c379; line-height: 26px">" 释放了锁"</span>)  <br/>        }  <br/>    }  <br/>    <span style="color: #5c6370; font-style: italic; line-height: 26px">// 创建多个线程来访问临界区  </span><br/>    <span style="color: #c678dd; line-height: 26px">for</span> (i in <span style="color: #d19a66; line-height: 26px">0</span>..<<span style="color: #d19a66; line-height: 26px">2</span>) {  <br/>        <span style="color: #c678dd; line-height: 26px">new</span> Thread(task).start()  <br/>    }  <br/>}<br/></code>
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaConcurrencydeadlockjava.util.concurrentlivelockThread Starvation
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.