线程的睡眠和等待
sleep是Thread类中提供的用于让线程暂停的方法,可以指定要暂停的时间(毫秒值)
wait则是object中提供的方法,会让当前线程等待,直到被唤醒为止
区别在于线程在阻塞的过程中是否会释放锁?
- sleep在阻塞的过程中是不释放锁的
- wait在阻塞的过程中是会释放锁的
- 首先我们通过代码来看一下Sleep的特点
public class SleepMethod {
public static void main(String[] args) {
//创建任务
PrimeRun primeRun = new PrimeRun();
//创建线程
Thread t1 = new Thread(primeRun,"线程A");
t1.start();
Thread t2 = new Thread(primeRun,"线程B");
t2.start();
}
}
class PrimeRun implements Runnable{
private int count = 5;
@Override
public void run() {
while(true) {
synchronized (PrimeThread.class) {
try {
System.out.println("线程"+Thread.currentThread().getName()+"获取锁并执行任务");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前是线程"+Thread.currentThread().getName()+"离开锁");
}
}
}
}
线程线程A获取锁并执行任务
当前是线程线程A离开锁
线程线程B获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程B离开锁
线程线程A获取锁并执行任务
当前是线程线程A离开锁
我们可以观察到sleep在线程睡眠的时候是不释放锁的,线程A进去,先输出一个A获取锁并执行任务然后睡眠,然后线程B进不来,要等线程A睡眠结束输出离开锁之后。线程B才能进入
- 接着我们观察一下wait的特点
public class WaitMethod {
public static void main(String[] args) {
// 创建一个唯一锁
Object object = new Object();
// 创建线程
PrimeThread t1 = new PrimeThread(object, "线程A");
t1.start();
PrimeThread t2 = new PrimeThread(object, "线程B");
t2.start();
}
}
/**
* wait在进行等待时会释放锁
*/
class PrimeThread extends Thread {
private int count = 5;//控制一下循环次数
private Object object;
public PrimeThread() {
}
public PrimeThread(Object object, String threadName) {
super.setName(threadName);
this.object = object;
}
@Override
public void run() {
while (count > 0) {
synchronized (object) {
try {
--count;
System.out.println("线程" + Thread.currentThread().getName() + "获取锁并执行任务");
// 在线程进行等待之前,先去唤醒其他的线程(睡之前先喊个人)
object.notify();//可以尝试一下注释掉唤醒这一过程(如果注释掉唤醒,再不加等待时间,两个线程就会进入永久等待)
object.wait();//object作为唯一的锁对象,在这还可以做监视器
//线程A先进获得锁并执行任务,然后唤醒线程B,线程B进获得锁并执行任务,然后线程B唤醒线程A,自己睡眠,然后线程A输出离开锁。
//然后新干线再进获得锁并执行任务,唤醒飞跃号..........
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前是线程" + Thread.currentThread().getName() + "获取锁");
}
}
}
结果
线程线程A获取锁并执行任务
线程线程B获取锁并执行任务
当前是线程线程A离开锁
线程线程A获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程A离开锁
线程线程A获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程A离开锁
线程线程A获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程A离开锁
线程线程A获取锁并执行任务
当前是线程线程B离开锁
线程线程B获取锁并执行任务
当前是线程线程A离开锁
可以发现,wait在线程等待的时候是会释放锁的,其他的进程可以在被锁住的线程等待期间进入锁并运行线程