提问:wait()和sleep()之间的区别??
wait()和之间的sleep()线程有什么区别?
我是否了解wait()-ing线程仍处于运行模式并使用CPU周期,但是sleep()-ing不会消耗任何CPU周期正确吗?
为什么我们都 wait()和sleep():如何实现他们在一个较低的水平有什么不同?
高分回答:
很多的知识点,真的需要写出来才会掌握!!! \color{purple}很多的知识点,真的需要写出来才会掌握!!!{~}很多的知识点,真的需要写出来才会掌握!!!
Await可以被另一个notify正在等待等待的监视器调用的线程“唤醒”,而sleep则不能。此外,wait(和notify)必须在synchronized监视对象的块中发生,而sleep不会:
Object mon = ...;
synchronized (mon) {
mon.wait();
}
复制代码
此时,当前正在执行的线程将等待并释放监视器。另一个线程可能会做
synchronized (mon) {
mon.notify();
}
复制代码
(在同一mon对象上),第一个线程(假设它是监视器上等待的唯一线程)将被唤醒。
您还可以notifyAll在监视器上等待多个线程的情况下进行调用-这将唤醒所有线程。但是,只有一个线程将能够抓住监视器(请记住,它们wait在一个synchronized块中)并继续运行-然后其他线程将被阻塞,直到它们可以获取监视器的锁为止。
另一点是,你叫wait上Object本身(即您等待对象的监视器上),而你打电话sleep的Thread。
另一个问题是,你可以得到虚假唤醒从wait(即线程正在等待简历没有明显的原因)。在某些情况下,您应始终wait按以下步骤旋转:
synchronized {
while (!condition) { mon.wait(); }
}
复制代码
高分回答
sleep(n)说:“我已经完成了时间片,请在至少n毫秒内不要再给我另一个时间片。” 在请求的时间过去之前,操作系统甚至不会尝试调度休眠线程。
yield()说:“我已经完成了时间片,但是我还有很多工作要做。” 操作系统可以自由地立即给线程另一个时间片,或者给其他线程或处理CPU放弃的收益线程。
wait()说:“我已经完成了时间片。在有人致电notify()之前,不要给我另一个时间片。” 与一样sleep(),除非有人打电话notify()(或发生其他一些唤醒情况之一),否则操作系统甚至不会尝试安排您的任务。
文章翻译自 yl2gl72eozkinivz3vc6swkesy-ac4c6men2g7xr2a-translate.translate.goog/questions/1…
作者建议:第二个回答很有意思,sheep不用cpu,yiedl我一直要,wait我不用。
摘自源码片短:一些核心的定义
private volatile String name; // 线程的名字
// 线程的优先级,默认为5,可自行设置,越大代表可以获得的时间片几率越高
private int priority;
/* 是否是守护线程,守护线程在JVM结束时自动销毁 */
private boolean daemon = false;
/* 将要运行的目标. */
private Runnable target;
/* 线程组-就是给线程分组,挺简单,初始化会被分配,与线程池无直接联系 */
private ThreadGroup group;
/* 此线程的上下文ClassLoader */
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
private AccessControlContext inheritedAccessControlContext;
/* 用于命名是哪个线程的编号 */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
/* 与此线程有关的ThreadLocal值。该映射由ThreadLocal类维护 */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
*与此线程有关的InheritableThreadLocal值。该映射由InheritreadLableThocal类维护.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
/*
此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0。
VM可以根据此数字执行*喜欢的任何事情;一些虚拟机将忽略它.
*/
private long stackSize;
/*
* Thread ID
*/
private long tid;
/* 用于生成线程ID */
private static long threadSeqNumber;
/* Java thread status
*/
private volatile int threadStatus = 0;
复制代码
注意几个重要的方法:
1.有一个start方法,这个方法里面调用了操作系统,利用操作系统去调用我们的run方法。
private native void start0();
- interruput方法,这只是一个标志,不会立即中断
interrupted()是静态方法:内部实现是调用的当前线程的isInterrupted(),并且会重置当前线程的中断状态
isInterrupted()是实例方法,是调用该方法的对象所表示的那个线程的isInterrupted(),不会重置当前线程的中断状态
- join 面试常问:其实是通过wait来阻塞线程,例如:t1.join(),无限制阻塞t1完成,在继续执行下面的方法。
- getAllStackTraces 获取所有线程的堆栈信息,可以用来扩展监控。
其他方法大家看看就行。
下面讲讲线程的状态:
/**
尚未启动的线程的线程状态
*/
NEW,
/**
可运行线程的线程状态。状态为可运行的线程正在Java虚拟机中执行,
但是可能正在等待来自操作系统的其他资源,例如处理器。
*/
RUNNABLE,
/**
线程的线程状态被阻塞,等待监视器锁定。处于阻塞状态的线程正在等待监视
器锁定输入同步块/方法或调用Object.wait后重新输入同步块/方法。
区别就是有个while
*/
// synchronized(this)
// {
// while (flag)
// {
// obj.wait();
// }
// }
BLOCKED,
/**
*等待线程的线程状态。由于调用以下其中一种方法,线程处于等待状态:
Object.wait无超时
Thread.join没有超时
LockSupport.park 等待状态
正在等待另一个线程执行特定操作。例如,在某个对象上调用
Object.wait()的线程正在等待另一个线程调用 Object.notify()
或该对象上的Object.notifyAll()名为 Thread.join的线程正在等待指定
的线程终止。
*/
WAITING,
/**
具有指定等待时间的等待线程的线程状态。线程由于以指定的正等待时间调用以下
方法之一而处于定时等待状态:
Thread.sleep,
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos
LockSupport.parkUntil
*/
TIMED_WAITING,
/**
终止线程的线程状态。*线程已完成执行
*/
TERMINATED;
复制代码
多了解,很有用的,方便查看线程的堆栈日志。
欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!! \color{red}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!!{~}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!!
有最新、优雅的实现方式,我也会在文末写出我对本问答的见解 \color{red}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解{~}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解
真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话
求点赞???? 求关注❤️ 求分享???? 对8块腹肌的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️