Thread.sleep(long millis) : 使当前线程暂停指定时间,暂停期间该线程不参与CPU竞争;
```java
@FastNative
private static native void sleep(Object lock, long millis, int nanos)
throws InterruptedException;
```
1. 不会释放占有的锁。
2. 必须传入时间,到时会自动唤醒(无法主动唤醒,醒后继续执行后续代码)。
3. Thread.sleep(0);//传入的时间为 【0】 或 【线程到时唤醒】,都会触发操作系统重新进行CPU竞争,竞争后也许是当前线程获得CPU控制权,也许是其他线程(和线程优先级有一定关系)。
Thread.yield();//线程让步
```java
public static native void yield();
```
1. 不会释放占有的锁。
2. 使当前线程从运行状态转到可运行状态,而不是等待或阻塞状态。
3. 使当前线程放弃执行的机会,让给其他线程执行(优先级高的只是概率大,也不一定必然就执行)。当前线程让出CPU权限后,CPU竞争后也有可能被再次执行。
Object.wait()(thread.wait(1000); thread.notify();调用的就是Object的方法)
```java
@FastNative
public final native void wait() throws InterruptedException;
@FastNative
public final native void wait(long millis, int nanos) throws InterruptedException;
@FastNative
public final native void notify();
```
1. 会释放占有的锁(调用后线程进入WAITING状态),时间可传可不传,不传表示一直阻塞下去;
2. 不带时间的方法,需要另一个线程使用 Object.notify() 才能唤醒;
3. 带时间的,假如没有被notify,到时会自动唤醒,这时又分好两种情况,一是立即获取到了锁,线程自然会继续执行;二是没有立即获取锁,线程进入同步队列等待获取锁;
4. 如果在wait()之前执行了notify()会抛出 IllegalMonitorStateException 异常;
对线程的等待和唤醒,推荐使用如下方法:
//如果在park()之前执行了unpark()会怎样?线程不会被阻塞,直接跳过park(),继续执行后续内容;
LockSupport.park(Object blocker);//parkNanos(long nanos)//阻塞,等待,挂起
LockSupport.unpark(thread)
1. 不会释放锁资源,不需要捕获中断异常
2. 底层是调用的Unsafe的native方法;
3. 可以被另一个线程调用LockSupport.unpark()方法唤醒;
4. 不带超时的,需要另一个线程执行unpark()来唤醒,一定会继续执行后续内容;