start() 方法用于启动线程,当一个线程调用 start() 方法,则意味着该线程进入就绪状态,等待线程调度
run() 方法只是 Thread 类的一个普通方法,其中保存着该线程需要完成的工作】
start() 方法是真正意义上启动一个线程,参与线程调度,而调用 run() 方法并没有启动一个新的线程,如果在主线程中调用一个线程的 run() 方法,则 run() 方法的内容仍然是主线程执行
sleep() 方法会让当前线程从 Running 状态进入 Timed Waiting 状态
需要注意的是,sleep() 作为 Thread 类的一个静态方法,与谁调用他无关,只会将当前线程睡眠
import lombok.SneakyThrows; public class SleepAndYield { public static void main(String[] args) throws InterruptedException { Thread t = new Thread() { @SneakyThrows @Override public void run() { for(int i = 0; i < 9999999; i ++) { System.out.println(i); } } }; t.start(); t.sleep(5000); } }
在主线程中,通过 t.sleep() 的方式希望让子线程进入睡眠,但并不会起作用,这里的 t.sleep() 相当于 Thread.sleep() ,恰恰是让主线程睡眠,故一般在使用 sleep() 时,也是用 Thread.sleep() 的形式
在其它线程中,可以通过 interrupt() 方法打断睡眠,原睡眠线程抛出 InterruptedException
public class SleepAndYield { public static void main(String[] args) throws InterruptedException { Thread t = new Thread() { @Override public void run() { System.out.println("enter sleep"); try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("interrupt success"); e.printStackTrace(); } } }; t.start(); Thread.sleep(1000); System.out.println("interrupt"); t.interrupt(); } }
抛出异常后,被 catch 捕获,进行处理
通过 TimeUnit 实现线程睡眠,效果与 Thread.sleep() 完全一致,但大大增强了可读性
TimeUnit.DAYS.sleep(1); //天 TimeUnit.HOURS.sleep(1); //小时 TimeUnit.MINUTES.sleep(1); //分 TimeUnit.SECONDS.sleep(1); //秒 TimeUnit.MILLISECONDS.sleep(1); //毫秒 TimeUnit.MICROSECONDS.sleep(1); //微秒 TimeUnit.NANOSECONDS.sleep(1); //纳秒
yield() 方法会让当前线程从 运行状态 进入 可运行状态,与 sleep() 不同,yield() 并非让线程阻塞等待,而是让出当前占用的 CPU 时间片,但在下一次线程调度中仍然有机会占用时间片
与 sleep() 相似,也是使用 Thread.yield() 调用
getPriority() 用于获取线程优先级,setPriority() 用于设置线程优先级,与 sleep() 和 yield() 不同,这两个方法都用线程对象调用
优先级使用 1 ~ 10 的整数表示,默认优先级为 5 ,优先级越高,在线程调度时被分配到 CPU 时间片的概率更大
join() 方法用于等待指定线程运行结束,可传入参数表示最多等待时间,如 join(1000) 表示最多等待1000毫秒,若 1000 毫秒后线程未运行结束,则停止等待,若在 1000 毫秒内线程已经结束,如线程运行只需要 500 毫秒,那么也会停止等待,而不是继续等待直到 1000毫秒,特殊的是,join(0) 与 join() 等价,该方法同样也通过线程对象调用
import lombok.SneakyThrows; public class JoinTest { static int value = 0; public static void main(String[] args) throws InterruptedException { System.out.println("开始"); Thread t = new Thread() { @SneakyThrows @Override public void run() { System.out.println("start"); sleep(1000); value = 10; System.out.println("end"); } }; t.start();; t.join(); System.out.println("结果为:" + value); System.out.println("结束"); } }
该示例中,主线程中通过 t.join() ,等待 t 线程执行结束,再输出被线程 t 修改过的 value
对于 interrupt() ,用于线程的打断
public class InterruptTest { public static void main(String[] args) throws InterruptedException { Thread t = new Thread() { @Override public void run() { while (true) { boolean interrupted = Thread.currentThread().isInterrupted(); if(interrupted) { System.out.println("break"); break; } } } }; t.start(); Thread.sleep(100); System.out.println("interrupt"); t.interrupt(); } }
该示例在主线程中打断 t 线程,t 线程监视中断标记,一旦为 true ,表示收到打断信号,跳出循环
对于 isInterrupted() 与 interrupted() ,用于检测线程是否被打断