线程通信基础(面向厕所编程)

一、sleep与wait的区别
先举例,在理论
公厕(公厕的坑位是共享资源)中无论多少人(人是线程)排队,只要你锁好厕门(synchronized)就不会出现线程安全问题,无论排队的多么着急都要一个个来,锁门期间(同步代码块内/同步方法内)调用sleep相当于你蹲坑期间睡着了,那么门锁(同步锁)肯定不会自动打开,依然是锁着的,除非时间到了你睡醒了然后该干嘛干嘛,否则只能通过粗暴的方式先把你叫醒(interreput方法)再说。wait相当于你礼让他人,先主动打开门锁(wait调用后会释放同步锁)让出坑位给别人,然后主动去加入排队蹲坑的大部队中边睡觉(进程陷入阻塞态)边等待。

二 、notify和notifyAll()
如果有人上完厕所,出来后看到睡眠中的排队者们,可以通过只叫醒一个(notify),但叫醒的一定是憋的最着急的人(优先级最高的线程),被叫醒的人能立刻获得坑位资源,也可以选择一次性唤醒所有(notifyAll)排队者,这时排队者会一窝蜂涌入争强坑位,可无论多么激烈,只能有一个人抢占坑位,优先级越高的线程抢到茅坑资源的概率越大

sleep和wait都是用来进行线程控制,都可以使线程阻塞
1 sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用interreput()来强行打断;wait()可以用notify()/notifyAll()直接唤起.

  1. sleep是Thread类的静态方法。 sleep的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达事件事恢复线程 ; wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者
  2. sleep()是让某个线程暂停运行一段时间,其控制范围是由当前线程决定,wait()是由某个确定的对象来调用的。

sleep和wait的区别有:
1、这两个方法来自不同的类分别是Thread和Object
2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

经典案例,交替打印0~9

public class Accounter implements Runnable{

    private int index;
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        synchronized (this){
            while (index < 10){
                notify();
                System.out.println(name + "打印:" + index);
                index++;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Accounter accounter = new Accounter();
        Thread thread = new Thread(accounter);
        Thread thread2 = new Thread(accounter);
        thread.start();
        thread2.start();
    }
}

添加新评论