java 线程相关
java线程守护线程
Java中的守护线程(Daemon Thread)和非守护线程(User Thread或Foreground Thread)主要区别在于它们对JVM生命周期的影响:
守护线程
- 守护线程通常为其他线程提供服务或者执行清理类型的任务,并不直接影响程序的正常终止流程。
- 当JVM中没有非守护线程在运行时,即使守护线程仍在运行,JVM也会停止运行,不会等待守护线程完成其任务。
- JVM垃圾回收器就是一个典型的守护线程示例,它在后台默默地执行清理工作,而不会阻止程序的结束。
非守护线程
- 也称为用户线程,是程序的主要工作线程,执行程序的主要任务逻辑。
- 当一个Java应用程序中只有非守护线程还在运行时,JVM会继续运行,直到所有非守护线程都结束为止。
- 如果所有的非守护线程都终止了,即使还有守护线程在运行,JVM也会退出。
java线程方法
线程的5 中状态
- 新建状态 new:新创建了一个线程对象
- 可运行状态 runnable:线程创建后,调用他的start方法,进入可运行状态。
- 运行 running:可运行状态的线程获取了cpu的执行。
- 阻塞状态 blocked:阻塞状态是指线程因为某种原因放弃了cpu使用权,暂时停止运行,阻塞的情况分为3中:
- 等待阻塞:运行的线程执行了wait()方法,jvm会把线程放入等待队列中。
- 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则jvm会把该线程放入锁池中。
- 其他阻塞:运行的线程执行sleep或join方法,或者发出了io请求,jvm会把该线程置为阻塞状态。当sleep状态超时、join等待线程终止或者超时、或者io处理完毕时,线程重新转入可执行状态。
- 死亡状态dead:线程run方法执行完后,该线程生命周期结束。
中断线程
thread.interrupt
public void interrupte();
线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位为true,线程仍会继续运行。
中断的线程结果是死亡、还是等待新的任务或是继续运行至下一步,取决于这个线程本身。线程会不时的检测这个中断状态位(检测是否为true),他并不会像stop方法那样会中断一个正在运行的线程。
interrupted()
public static boolean interrupted();
测试当前线程是否已被中断(检查中断标志),返回一个boolean并清除中断状态,第二次在调用时中断状态已经被清除,将返回一个false
isInterrupted
public boolean isInterrupted()
测试次线程是否被中断,不清除中断状态。
sleep()
- sleep并不会释放线程占用的锁,只是让出了cpu。
wait()
- wait则会释放锁,只有针对此对象调用notify或者notify all才能唤醒线程。
- wait()方法是Object类的native方法.
join
源码解析
举例,在main方法中执行t1.join(),这里要区分2个概念,
- main线程执行的t1.join
- t2线程执行的join()
这2个现成是不同的线程。
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) {
//isAlive是判断调用a.join方法的线程对象a是不是运行状态
while (isAlive()) {
//wait方法是让 执行a.join的 现成继续等待
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
- join方法的作用是 调用join方法的线程结束后,程序才可以继续往下执行。