Java基础(七):sleep()和wait(),notify()和 notifyAll(),run()和 start()的区别

sleep()和wait()区别:

  • sleep(long millis) 属于Thread类,参数为毫秒
  • wait() 属于Object类
  • 当调用sleep()方法时,程序会休眠指定的时间,持有的锁不会释放。
  • 当调用wait()方法时,程序会挂起,并释放锁,直到线程执行notify()方法或者notifyAll()方法或者时间到期。
  • wait()方法只能在同步控制方法或者同步控制块里调用(notify()、notifyAll()也是)。而sleep方法不用,因为不用操作锁。如果在非同步控制方法里调用,编译能通过,但是在运行的时候,会报IllegalMonitorStateException异常,因为调用这些方法前必须“拥有”(获取)对象的锁。

为什么wait()被设计在Object类里?

  • 因为这些方法操作的锁也是所有对象的一部分,所以你可以把wait()方法放到任何同步控制里,而不用考虑这个类是继承自Thread还是实现了Runnable接口。

 

notify()和 notifyAll()区别:

  • 都属于Object类。
  • notify()通知一个等待的线程,如果有多个等待的线程,则任意唤起其中一个,具体规则由实现类决定。
  • notifyAll()则唤起所有等待的线程。
  • 两者都不会立刻执行,需要等到当前线程释放该对象上的锁。被唤起的线程和其他线程一样以通常的方式竞争。

 

run()和 start()区别:

  • 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。
  • run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

 

示例:

//先打蜡,再抛光
public class Car {
    //打蜡
    private boolean waxOn = false;

    public synchronized void waxed() {
        waxOn = true;//已打蜡,可以抛光了
        notifyAll();
    }

    public synchronized void buffed() {
        waxOn = false;//可以涂另一层蜡了
        notifyAll();
    }

    public synchronized void waitForWaxing() throws InterruptedException {
        while (!waxOn) {
            wait();
        }
    }

    public synchronized void waitForBuffing() throws InterruptedException {
        while (waxOn) {
            wait();
        }
    }
}

public class WaxOn implements Runnable {

    private Car car;

    public WaxOn(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("打蜡开始!!!");
                car.waxed();
                System.out.println("等待抛光!!!");
                car.waitForBuffing();
                Thread.sleep(200);
                car.buffed();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class WaxOff implements Runnable {

    private Car car;

    public WaxOff(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println("等待打蜡!!!");
                car.waitForWaxing();
                Thread.sleep(200);
                System.out.println("抛光结束!!!");
                car.buffed();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test(){
    Car car = new Car();
    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.execute(new WaxOff(car));
    executorService.execute(new WaxOn(car));
    Thread.sleep(2000);
    executorService.shutdownNow();
}


//输出结果:
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值