//使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性。线程不会丢失任何监视器的所有权
//如果有线程中断了当前的线程(调用Thread.sleep(..)方法的线程),则会抛出 InterruptedException 异常,并且抛出此异常之后,当前线程的中断状态将被清除
public static native void sleep(long millis) throws InterruptedException;
//精确到纳秒级别
public static native void sleep(long millis, int nanos) throws InterruptedException;
//如果某个线程调用了 wait(..)、join(..)、sleep(..)方法被阻塞后调用了这个方法,会清除中断状态,并抛出异常(翻译)
//中断一个非活动线程没有任何效果
public void interrupt() {
...}
//向调度器声明可以让出 CPU 时间,调度器可以忽略该声明,继续让该线程执行
//Yield是一种启发式尝试,用于改善线程之间的相对进展,否则会过度利用CPU。 它的使用应与详细的分析和基准测试相结合,以确保它实际上具有所需的效果。
//这个方法很少使用。 它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误。 在设计并发控制结构(例如java.util.concurrent.locks包中的结构)时,它也可能很有用
public static native void yield();
public final native void wait(long timeout) throws InterruptedException;
//很奇怪, nanos 参数只要在 0< nanos< 999999 之内,该方法会直接调用 wait(++timeout),即都只是多了一个毫秒数
public final native void wait(long timeout, int nanos) throws InterruptedException;
当前线程必须拥有一个监视器(在 synchronized 块之内)对象
唤醒正在等待此对象监视器的单个线程。如果有任何线程正在等待这个对象,那么将选择唤醒其中一个线程。选择是任意的
被唤醒的线程必须等待当前线程放弃监视器(退出 synchronized 块)后,才能继续
public final native void notify();
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
//判断this对象线程是否存活,如果存活就一直等待!只有被唤醒了,并且this对象线程死了,才会退出 while!
wait(0);// 当 this 线程死之前,会调用 notifyAll() 方法,唤醒所有等待线程,
//所以,只有 this 线程死了,才会退出循环
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;//如果millis不为0,会从这里退出while循环!
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
public enum State {
//尚未启动的线程处于此状态。
NEW,
//在Java虚拟机中执行的线程处于此状态。但它可能正在等待来自操作系统的其他资源,例如 CPU 时间。
RUNNABLE,
//被阻塞等待监视器锁定的线程处于此状态。
//执行 synchornized 代码块,抢监视器锁失败后,进入此状态
BLOCKED,
//无限期等待另一个线程执行*特定操作*的线程处于此状态。
//调用 wait()、join()、LockSupport.park() 方法,进入无限等待状态
WAITING,
//在指定的等待时间内等待另一个线程执行操作的线程处于此状态。
//调用 wait(long)、join(long)、parkNanos()、parkUntil() 方法进入有限等待状态
TIMED_WAITING,
//已退出的线程处于此状态。线程完全执行完毕后
TERMINATED;
}
/***
* @Description: 调用 sleep 方法后线程进入 Time_Waiting 状态,且不会释放锁
*/
public void 调用sleep线程的运行状态和锁释放情况() throws InterruptedException {
Thread sleepTheard = new Thread(()->{
System.out.println(Thread.currentThread().getName() + " 的状态是:" + Thread.currentThread().getState().toString());
try {
synchronized (lock) {
System.out.println("获取锁了");
Thread.sleep(5000);
System.out.println("释放锁了");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
},"sleepThread");
sleepTheard.start();
Thread.sleep(1000);
System.out.println(sleepTheard.getName() + " 的状态是:" + sleepTheard.getState().toString());
synchronized (lock) {
System.out.println("才进入");
}
System.out.println(sleepTheard.getName() + " 的状态是:" + sleepTheard.getState().toString());
}
/**
* @Description: 调用sleep方法后,线程如果被中断,会抛出异常,并清除中断状态
*/
public void 调用sleep被中断后的状态() throws InterruptedException {
Thread sleepThread = new Thread(()->{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程被中断抛异常后是否是中断状态:" + Thread.currentThread().isInterrupted());
}
});
sleepThread.start();
Thread.sleep(200);
sleepThread.interrupt();
}
/**
* @Description: 中断一个非活动线程没有任何效果!
*/
public void 中断一个非活动线程没有任何效果() throws InterruptedException {
Thread sleepThread = new Thread(()->{
try {
Thread.sleep(1000);
System.out.println("线程运行了");
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("线程被中断抛异常后是否是中断状态:" + Thread.currentThread().isInterrupted());
}
});
sleepThread.interrupt();
System.out.println("线程被中断后是否是中断状态:" + sleepThread.isInterrupted());
sleepThread.start();
Thread.sleep(2000);
}
/**
* @Description: 调用interrupt后线程为中断状态
*/
public void 调用interrupt后线程的中断状态() throws InterruptedException {
Thread sleepThread = new Thread(()->{
while (flag) {
}
});
sleepThread.start();
Thread.sleep(200);
sleepThread.interrupt();
System.out.println("调用interrupt后线程是否是中断状态:" + sleepThread.isInterrupted());
flag = Boolean.FALSE;
}
public void 先调用interrupt后调用sleep() throws InterruptedException {
Thread t1 = new Thread(() -> {
while (flag) {
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程被中断抛异常后是否是中断状态:" + Thread.currentThread().isInterrupted());
e.printStackTrace();
}
});
t1.start();
Thread.sleep(1000);
t1.interrupt();
System.out.println("线程t1中断状态为:" + t1.isInterrupted());
flag = Boolean.FALSE;
Thread.sleep(2000);
}
public void yield声明让出CPU但可能继续执行() {
Thread t1 = new Thread(() -> {
while (true) {
Thread.yield();
System.out.print("1 ");
} });
Thread t2 = new Thread(() -> {
while (true) {
Thread.yield();
System.out.print("2 ");
}
});
t1.start();
t2.start();
// 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 1 2 2 2 2 2 1 1 1 1 1 1 1 ,说明确实让出CPU了(有一段特别规律),但可能继续执行(有一点整个都是一个线程的值)
}
public void 调用wait方法后线程的状态() throws InterruptedException {
Thread waitThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println(Thread.currentThread().getName() + " 调用 wait 方法之间的状态是:" + Thread.currentThread().getState().toString());
lock.wait(2000);
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"waitThread");
waitThread.start();
Thread.sleep(1000);
System.out.println(waitThread.getName() + " 调用 wait 方法之后的状态是:" + waitThread.getState().toString());
Thread.sleep(2000);
System.out.println(waitThread.getName() + " 调用 wait 方法之后的状态是:" + waitThread.getState().toString());
System.exit(0);
}
public void 调用join方法线程完了才会往下走() throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(40000);
System.out.println("0");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(1);
});
t.start();
t.join();
System.out.println("1");
}
JDK 1.8u171