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();
}
//输出结果:
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!
打蜡开始!!!
等待抛光!!!
抛光结束!!!
等待打蜡!!!