三种休眠状态:Blocked,Waiting,Timed_Waiting
注意两个Blocked态是不一样的,上面的Blocked只要睡眠时间到了马上进入运行态,下面处于Blocked的线程还需要抢到锁才能进入运行态
sleep()和wait()方法:
sleep():Thread.sleep(1000);
线程休眠指定时间,不会释放锁,也就是线程即使休眠也是一直保持锁的所有权的,等休眠时间一过,马上进入运行态,不用再去和其他处于blocked状态的线程一起竞争锁
wait方法:必须和synchronized配合使用
public class Test
{
public static void main(String[] args) throws InterruptedException
{
Object object=new Object();
new Thread( ()->{
synchronized(object)
{
System.out.println(Thread.currentThread().getName()+"开始运行");
object.wait();//执行到这行代码的时候,线程卡在这里了,进入了等待集合
System.out.println(Thread.currentThread().getName()+"我被唤醒了,我又重新开始运行了");
}
},"t1").start();
new Thread( ()->{
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"开始运行");
synchronized(object)
{
object.notify();
}
},"t2").start();
}
}
执行效果:
t1开始运行
t2开始运行
t1我被唤醒了,我又重新开始运行了
共享对象调用wait方法:obj.wait(),当前线程释A放锁,进入waiting阻塞状态,除非其他线程调用共享对象obj.notify()方法唤醒这个线程,线程A就会去竞争试图重新获得锁,如果获得锁就进入运行态,如果没有获得锁就进入blocked阻塞状态
wait(1000)就是设置阻塞时间,到达指定时间,即使没有其他线程调用共享对象obj.notify()方法唤醒这个线程,线程A也会自动苏醒,去竞争试图重新获得锁
sleep方法和wait()方法的区别
(1)使用方法不一样:wait属于Object类的方法,sleep属于Thread类的方法
(2)thread.sleep()方法不会释放对象锁,如果线程本身持有锁,那虽然休眠还是持有锁,而obj.wai()t方法会释放对象锁
(3)thread.sleep()可以不需要搭配synchronized使用,而obj.wait()必须搭配synchronized使用