现在找个网站这么难的吗,营销型网站的推广,wordpress付免签插件,辽宁身营商环境建设局网站一、sleep和wait区别
区别一#xff1a;语法使用不同
wait 方法必须配合 synchronized 一起使用#xff0c;不然在运行时就会抛出 IllegalMonitorStateException 的异常
而 sleep 可以单独使用#xff0c;无需配合 synchronized 一起使用。
区别二#xff1a;所属类不同…一、sleep和wait区别
区别一语法使用不同
wait 方法必须配合 synchronized 一起使用不然在运行时就会抛出 IllegalMonitorStateException 的异常
而 sleep 可以单独使用无需配合 synchronized 一起使用。
区别二所属类不同
wait 方法属于 Object 类的方法而 sleep 属于 Thread 类的方法
区别三唤醒方式不同
sleep 方法必须要传递一个超时时间的参数且过了超时时间之后线程会自动唤醒。而 wait 方法可以不传递任何参数不传递任何参数时表示永久休眠直到另一个线程调用了 notify 或 notifyAll 之后休眠的线程才能被唤醒。也就是说 sleep 方法具有主动唤醒功能而不传递任何参数的 wait 方法只能被动的被唤醒。
区别四释放锁资源不同
wait 方法会主动的释放锁而 sleep 方法则不会。接下来我们使用代码的方式来演示一下二者的区别。
sleep 不释放锁
接下来使用 sleep 是线程休眠 2s然后在另一个线程中尝试获取公共锁如果能够获取到锁则说明 sleep 在休眠时会释放锁反之则说明不会释放锁
在调用了 sleep 之后在主线程里尝试获取锁却没有成功只有 sleep 执行完之后释放了锁主线程才正常的得到了锁这说明 sleep 在休眠时并不会释放锁。
wait 释放锁
接下来使用同样的方式将 sleep 替换成 wait在线程休眠之后在另一个线程中尝试获取锁
当调用了 wait 之后主线程立马尝试获取锁成功了这就说明 wait 休眠时是释放锁的。
区别五线程进入状态不同
调用 sleep 方法线程会进入 TIMED_WAITING 有时限等待状态而调用无参数的 wait 方法线程会进入 WAITING 无时限等待状态。 总结
sleep 和 wait 都可以让线程进入休眠状态并且它们都可以响应 interrupt 中断但二者的区别主要体现在语法使用不同、所属类不同、唤醒方式不同、释放锁不同和线程进入的状态不同。 二、线程的状态Thread.State 三、供参考的多线程代码一、sleep和waitWAITING和TIMED_WAITING状态 public class Test04_ThreadState {public static void main(String[] args) {new Thread(new TimeWaiting(), TimeWaitingThread).start();new Thread(new Waiting(), WaitingThread).start();}/*** 该线程不断的进行睡眠*/static class TimeWaiting implements Runnable {Overridepublic void run() {while (true) {SleepUtils.second(100);}}}/*** 该线程在Waiting.class实例上等待*/static class Waiting implements Runnable {Overridepublic void run() {while (true) {synchronized (Waiting.class) {try {Waiting.class.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}} 四、查看线程运行状态的方法
1.jps
获得线程号和线程的类名 2.jstack 线程号
jstack 2636
看线程某个时刻的运行情况(线程的快照)
这里打印出来的是当前线程的快照dump。 3.jvisualvm可视化软件
在java的jdk目录下的bin目录下有jvisualvm.exe文件可以 打开软件后可以看到正在运行的进程如下图 可以在其中找到java代码创建的线程的名字对应的线程 可以看到WatingThread线程状态是WAITING等待状态
TimeWaitingThread线程状态是TIMED_WAITING超时等待状态
和我们这篇文章的 二、线程的状态Thread.State 对应。 五、案例
一、Blocked阻塞状态
Blocked阻塞状态代码 public class Test04_ThreadState {public static void main(String[] args) {new Thread(new Blocked(), BlockedThread-1).start();new Thread(new Blocked(), BlockedThread-2).start();}/*** 该线程在Blocked.class实例上加锁后不会释放该锁*/static class Blocked implements Runnable {Overridepublic void run() {synchronized (Blocked.class) {while (true) {SleepUtils.second(100);}}}}
}
Blocked阻塞状态代码jvisualvm查看
由于BlockedThread-1先创建抢占到了系统资源运行后拿到了锁并调用了sleep方法因此进入TIMED_WAITING超时等待状态而BlockedThread-2拿不到锁因此进入Blocked阻塞状态。线程快照dump如下图 Blocked阻塞状态代码总结
1.触发Blocked状态的原因
由于BlockedThread-1先创建抢占到了系统资源运行后拿到了锁并调用了sleep方法因此进入TIMED_WAITING超时等待状态而BlockedThread-2拿不到锁因此进入Blocked阻塞状态。
2.sleep方法
由于sleep方法不会释放锁因此BlockedThread-2无法拿到锁进入阻塞状态更加验证了sleep方法不会释放锁。
二、ReentrantLock可重入锁
ReentrantLock可重入锁代码 public class Test04_ThreadState {private static Lock lock new ReentrantLock();public static void main(String[] args) {new Thread(new Sync(), SyncThread-1).start();new Thread(new Sync(), SyncThread-2).start();}static class Sync implements Runnable {Overridepublic void run() {lock.lock();try {SleepUtils.second(100);} finally {lock.unlock();}}}
}
ReentrantLock可重入锁代码jvisualvm查看 ReentrantLock可重入锁代码总结
1.synchronized和ReentrantLock区别简略描述之后会详细补充
ReentrantLock锁更加面向对象 两个锁加锁之后另外一个线程进入状态不一样 synchronized进入blocked状态是被动的 还没有进入到同步代码块中 ReentrantLock是一种主动进入锁的状态 已经进入到代码块中 程序恢复之后 它会从等待的位置继续执行 最后总结 a.线程的状态 jps看线程的线程号 jstack看线程某个时刻的运行情况(线程的快照) jvisualvm对线程进行dump b.线程调用sleep 进入TimeWaiting状态 不会释放锁 c.线程调用wait 进入Waiting状态 会释放锁 d.A线程进入B线程已经拿到锁(synchronized) A线程会进入阻塞状态blocked状态 e.当A线程进入B线程已经拿到锁(lock) A线程会进入等待状态waiting状态 f.synchronized和lock区别 1.lock锁更加面向对象 2.两个锁加锁之后另外一个线程进入状态不一样 synchronized是blocked状态lock是waiting状态 3.synchronized进入blocked状态是被动的 还没有进入到同步代码块中 4.lock是一种主动进入锁的状态 已经进入到代码块中 程序恢复之后 它会从等待的位置继续执行 如果你不太理解synchronized锁的对象是什么你可以看下面这篇文章
synchronized锁的对象是什么