sleep(),wait(),join(),yield(),suspend(),resume()方法

本文深入探讨了Java中线程控制的关键方法,包括sleep()、wait()、join()、yield()、suspend()和resume()的功能及使用场景,揭示了它们在并发控制中的作用和潜在的死锁风险。

1、sleep()

在Thread.class中对其描述为:

/**
     * 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.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

根据注释可以看出来,sleep()方法在执行的时候,导致当前的线程进入睡眠状态,但是当前线程并不会释放其占有的锁,唤醒的时候并不一定立刻进入运行状态,而是受定时器和调度器的精度和准确度(线程调用机制唤醒线程也是需要时间的)。

2、wait()

在Object.class中对其描述为

* This method causes the current thread (call it <var>T</var>) to
* place itself in the wait set for this object and then to relinquish
* any and all synchronization claims on this object. 

根据注释可以看出来,wait()执行的时候,线程会释放其同步锁中的资源,进入等待状态。唤醒方式有三种,如果wait中有timeout参数,则超时后可以唤醒,notify()和notifyAll()也可以唤醒。

3、join()

 /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

Thread.class对其描述为等待这个方法死亡,意思是先执行完这个方法,才可以执行原来的方法,通俗描述为插队。

其源码实现为:

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

解释为millis==0,如果该线程还存活则原有线程等待。执行的是wait(),即原有线程要释放自己的同步锁资源。

4、yield()    英语解释为谦让

Thread.class对其描述为

/**
     * 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();

yield()方法是释放自己的同步锁资源,进入就绪状态,告诉同样优先级的线程可以占用自己的资源,但是并不一定能够成功。

 

4、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();
    }

Thread.class对suspend()的描述是:当前线程调用suspend()方法会挂起直至恢复,但是这个方法被禁用了(不推荐使用),如果目标线程在监视器上保持锁定,在挂起时保护关键系统资源,则其他线程无法访问此资源,直到目标线程恢复为止。如果 resume() 操作出现在 suspend() 之前执行,那么线程将一直处于挂起状态,同时一直占用锁,这就产生了死锁。而且,对于被挂起的线程,它的线程状态居然还是 Runnable。这种死锁通常表现为“冻结”过程。

举个例子:

public class JoinTest {
    public static Integer NUM = 0;

    static class ThreadTest implements Runnable{
        private String name;

        public ThreadTest(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name+"start");
            synchronized (NUM){
                Thread.currentThread().suspend();
            }
            System.out.println(name+"over");
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Thread test = new Thread(new ThreadTest("thread-1-"));
        Thread test2 = new Thread(new ThreadTest("thread-2-"));
        test.start();
        Thread.sleep(200);
        test2.start();
        test2.resume();
        test.resume();
    }
}

结果为:

thread-1-start
thread-1-over
thread-2-start

查看jvm

线程已经死锁,但是显式为RUNNABLE.

6、resume()

/**
     * Resumes a suspended 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 but suspended, it is resumed and is
     * permitted to make progress in its execution.
     *
     * @exception  SecurityException  if the current thread cannot modify this
     *               thread.
     * @see        #checkAccess
     * @see        #suspend()
     * @deprecated This method exists solely for use with {@link #suspend},
     *     which has been deprecated because it is deadlock-prone.
     *     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 resume() {
        checkAccess();
        resume0();
    }

Thread.class调用resume(),为了恢复suspend()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值