Java 進階如何讓線程主動讓出 CPU Threadsleep Threadyield ThreadcurrentThreadsuspend Objectwait LockSupportpark Threadstop
Java 進階:如何讓線程主動讓出 CPU Thread.sleep
sleep 方法可以讓線程主動讓出 CPU,但是並不會釋放鎖。
/** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. The thread * does not lose ownership of any monitors. */ public static native void sleep(long millis) throws InterruptedException;
Thread.yield
yield 也可以讓線程主動讓出 CPU,然後和其他線程一起競爭 CPU,但是調度器也可以忽略 yield。哪些情況會用到 yield 呢。
1. 一般在 debug 和 test 中使用。
2. CPU 密集型應用主動讓出 CPU 以避免過度佔用 CPU,影響其他任務。
/** * A hint to the scheduler that the current thread is willing to yield * its current use of a processor. The scheduler is free to ignore this * hint. * * <p> Yield is a heuristic attempt to improve relative progression * between threads that would otherwise over-utilise a CPU. Its use * should be combined with detailed profiling and benchmarking to * ensure that it actually has the desired effect. * * <p> It is rarely appropriate to use this method. It may be useful * for debugging or testing purposes, where it may help to reproduce * bugs due to race conditions. It may also be useful when designing * concurrency control constructs such as the ones in the * {@link java.util.concurrent.locks} package. */ public static native void yield();
Thread.currentThread().suspend()
該方法已淘汰。為啥呢。suspend 掛起線程,並不會釋放鎖,又不像 sleep 那樣一段時間後自動回復,所以容易引起死結。相對應的 resume 方法用於喚醒一個 suspend 的線程。
/** * Suspends this thread. * <p> * First, the <code>checkAccess</code> method of this thread is called * with no arguments. This may result in throwing a * <code>SecurityException </code>(in the current thread). * <p> * If the thread is alive, it is suspended and makes no further * progress unless and until it is resumed. * * @exception SecurityException if the current thread cannot modify * this thread. * @see #checkAccess * @deprecated This method has been deprecated, as it is * inherently deadlock-prone. If the target thread holds a lock on the * monitor protecting a critical system resource when it is suspended, no * thread can access this resource until the target thread is resumed. If * the thread that would resume the target thread attempts to lock this * monitor prior to calling <code>resume</code>, deadlock results. Such * deadlocks typically manifest themselves as "frozen" processes. * For more information, see * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>. */ @Deprecated public final void suspend() { checkAccess(); suspend0(); } @Deprecated public final void resume() { checkAccess(); resume0(); }
Object.wait
wait 會把當前持有的鎖釋放掉同時阻塞住,讓出 CPU。當其他線程調用 Object.notify/notifyAll 時,會被喚醒,可能得到 CPU,並且獲得鎖。 LockSupport.park
這就是鎖了嘛,相對應的用 unpark 解鎖。 Thread.stop
該方法已淘汰,直接停止線程,同時會釋放所有鎖,太過暴力,容易導致資料不一致。