java面试系列--J2SE基础(十二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weisong530624687/article/details/79452520

28. wait()和sleep()的区别。

wait是java.lang包的,属于Object的方法,
sleep是属于Thread的方法;

wait的时候,当前线程会释放资源锁,然后进入等待锁定池,只有针对此对象调用notify方法后本线程才会继续执行,
sleep的时候,当前资源锁并没有释放,直到sleep结束然后继续执行;

sleep的时候一般都要对异常进行处理,捕捉或外抛,而且sleep方法是一个静态方法,可以在任何地方使用,而且只对当前对象有效,
wait,notify和notifyAll不需要捕获异常,只能在同步控制方法或者同步控制块里面使用;

sleep和wait都会在调用执行中被interrupt。


另外三个方法:interrupt()/join()/yield()

void interrupt()  中断线程。
void join() 等待该线程终止。
static void yield() 暂停当前正在执行的线程对象,并执行其他线程。


    /**
     * 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是一个静态的原生(native)方法;
yield告诉当前正在执行的线程可以暂停执行,把运行机会交给拥有相同优先级的线程;
执行yield()的线程有可能在进入到可执行状态后马上又被执行,因为没有其他要执行的线程;


    /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait 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 final synchronized void join(long millis)
join方法是用于在某一个线程A的执行过程中调用另一个线程B执行,B.join,则等到被调用的线程B执行结束后,再继续执行当前线程A。

其他资源参考:

Java中wait 和sleep 方法比较 http://wkf41068.iteye.com/blog/1835697
JAVA—sleep()和wait()的区别 http://blog.csdn.net/clam_clam/article/details/6803667
Java中wait和sleep方法的区别 https://www.cnblogs.com/loren-Yang/p/7538482.html
Java线程中yield与join方法的区别 http://www.importnew.com/14958.html

java中的sleep()和wait()的区别 https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

源代码事例:

看了很多的代码,有的没看明白,有的感觉说的含糊,有的感觉实地测试和原文描述有冲突,归根结底,感觉下面这个列子让人一目了然,通俗易懂,现摘录如下,原文来自 https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

package com.ws.thread;

/**
 * java中的sleep()和wait()的区别
 */
public class TestD {

	public static void main(String[] args) {
		new Thread(new Thread1()).start();
		try {
			Thread.sleep(5000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		new Thread(new Thread2()).start();
	}

	private static class Thread1 implements Runnable {
		@Override
		public void run() {
			synchronized (TestD.class) {
				System.out.println("enter thread1...");
				System.out.println("thread1 is waiting...");
				try {
					// 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池
					TestD.class.wait();
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("thread1 is going on ....");
				System.out.println("thread1 is over!!!");
			}
		}
	}

	private static class Thread2 implements Runnable {
		@Override
		public void run() {
			synchronized (TestD.class) {
				System.out.println("enter thread2....");
				System.out.println("thread2 is sleep....");
				// 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
				TestD.class.notify();
				// ==================
				// 区别
				// 如果我们把代码:TestD.class.notify();给注释掉,即TestD.class调用了wait()方法,但是没有调用notify()
				// 方法,则线程永远处于挂起状态。
				try {
					// sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,
					// 但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
					// 在调用sleep()方法的过程中,线程不会释放对象锁。
					Thread.sleep(5000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("thread2 is going on....");
				System.out.println("thread2 is over!!!");
			}
		}
	}
}

运行结果:


按照注释,注释掉notify之后,运行结果:



打赏

如果觉得我的文章对你有帮助,有钱就捧个钱场,没钱就捧个人场,欢迎点赞或转发 ,并请注明原出处,谢谢....





扫描二维码关注公众号,回复: 3513855 查看本文章


猜你喜欢

转载自blog.csdn.net/weisong530624687/article/details/79452520