一、大纲
sleep()
yield()
join()
线程优先级
高效结束线程
二、详述
2.1、
线程睡眠——
sleep()
注意 :
sleep()
是 静态方法
,最好不要用Thread的实例 对象
调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。
2.2、
线程礼让——
yield()
yield()
方法只是让当前线程 暂停
一下,重新进入就绪的线程池中,让系统的线程调度器重新调度器 重新调度一次
,所以有可能刚进入就绪状态,又被调度到运行状态
与 sleep()
的区别
sleep()
方法暂停当前线程后,会进入 阻塞
状态,只有当睡眠时间到了,才会转入 就绪
状态。 yield()
方法调用后 ,是直接进入 就绪
状态,所以有可能刚进入就绪状态,又被调度到 运行
状态。 sleep()
声明抛出了 InterruptedException
,所以调用 sleep()
方法的时候要捕获该异常,或者显示声明抛出该异常。 yield()
方法则没有声明抛出任务异常。 sleep()
方法比 yield()
方法有更好的 可移植性
,通常 不
要依靠 yield()
方法来控制并发线程的执行。
2.3、
线程合并 (插队)——
join()
1
使用 join()
后,线程 2
必须等待线程1执行完毕才能执行!,常常在一个线程的内部的 run()
方法,进行另一个线程的 join()
(插队)
void join();
当前线程等该加入该线程后面,等待该线程终止。
void join(long millis)
void join(long millis,int nanos)
2.4、
线程优先级 ——
Priority
main
线程具有普通优先级
使用: Thread
类提供了
setPriority(int newPriority)
设置1个指定线程的优先级 getPriority()
返回1个指定线程的优先级 Thread
类的静态成员变量进行设置,这样才能保证程序最好的可移植性。
2.5、
守护线程
- 它为用户线程提供后台支持任务的服务。 - 它在生命中没有为服务用户线程而发挥作用。 - 它的生命取决于用户线程。它是一个低优先级的线程。 - **用户线程都执行完,JVM会终止守护程序线程**
应用实例(守护线程通常用于执行一些后台作业)
JVM
的垃圾回收、内存管理等线程都是守护线程 public final void setDaemon(boolean on);` Thread t = new Thread( () -> { public void run() { //do something; } }); t.setDaemon(true); //该方法必须在 start() 启动线程前调用。 t.start();
IllegalThreadStateException - 如果该线程处于活动状态。 SecurityException - 如果当前线程无法修改该线程。
2.6、
如何高效地结束一个线程!
Thread.stop()、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExit
这些终止线程运行的方法已经被废弃了,使用它们是极端不安全的!
1、正常执行完 run()
方法,然后结束掉
class MyThread extends Thread { int i=0; @Override public void run() { while (true) { if (i == 10) break; i++; System.out.println(i); } } }
2、控制循环条件和判断条件的标识符来结束掉线程
class MyThread extends Thread { int i = 0; boolean next = true; @Override public void run() { while (next) { if(i == 10) next = false; i++; System.out.println(i); } } }
3、使用 interrupt()
这个巧妙的方式结束掉这个线程
3.1
第 2
种方法的标识符来结束一个线程,是一个不错的方法,但如果,该线程是处于 sleep()、wait()、join()
的状态的时候, while
循环就不会执行,那么我们的 标识符
就无用武之地了,
3.2
我们看看 sleep()、wait()、join()
方法的声明:
public final void wait() throws InterruptedException public static native void sleep(long millis) throws InterruptedException public final void join() throws InterruptedException
3.3
在什么时候会产生这样一个异常呢?
true
,那么它就会抛出一个 InterruptedException
的异常,并会将中断状态重新设置为 false
。 3.4 例子
public class Test { public static void main(String[] args) throws InterruptedException { MyThread thread=new MyThread(); thread.start(); } } class MyThread extends Thread { int i = 1; @Override public void run() { while (true) { System.out.println(i); System.out.println(this.isInterrupted()); try{ System.out.println("我马上去sleep了"); Thread.sleep(2000); this.interrupt(); //interrupt()方法将中断状态设置为true } catch (InterruptedException e){ System.out.println("异常捕获了" + this.isInterrupted()); return; } i++; } } }结果: 1. 1 2. false 3. 我马上去sleep了 4. 2 5. true 6. 我马上去sleep了 7. 异常捕获了false (1)首先执行第一次while循环,在第一次循环中,睡眠2秒,然后将中断状态设置为true。 (2)当进入到第二次循环的时候,中断状态就是第一次设置的true,当它再次进入sleep的时候, 马上就抛出了InterruptedException异常 (3)然后被我们捕获了。 (4)然后中断状态又被重新自动设置为false了(从最后一条输出可以看出来)