欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

三、网络编程之线程优先级和守护详解

一、线程优先级

线程可以划分优先级,优先级分为1-10的10个等级,数字越大优先级越高,优先级较高的线程得到CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务(其实并不是这样)。但是线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。

二、优先级具有继承性

线程是有继承关系的,比如当A线程中启动B线程,那么B和A的优先级将是一样的。

/**
* 线程优先级
*/
public class TheadTest4 {
   public static void main(String[] args) {
       Thread thread = new Thread(new A());
       thread.start();
   }
}

class A implements Runnable {

   @Override
   public void run() {
       System.out.println("A的优先级为:" + Thread.currentThread().getPriority());
       Thread thread = new Thread(new B());
       thread.start();
   }
}

class B implements Runnable {

   @Override
   public void run() {
       System.out.println("B的优先级为:" + Thread.currentThread().getPriority());
   }
}

三、setPriority设置优先级

更改线程的优先级。当使用了setPriority设置了优先级,但是线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。

/**
* 线程优先级
*/
public class TheadTest4 {
  public static void main(String[] args) {
      Thread thread1 = new Thread(new A());
      Thread thread2 = new Thread(new B());
      //将优先级设置到最低
      thread1.setPriority(10);
      //将优先级设置到最高
      thread2.setPriority(1);
      //线程启动
      thread1.start();
      thread2.start();
  }
}

class A implements Runnable {
  @Override
  public void run() {
      for (int i = 0; i <10 ; i++) {
          System.out.println("A的优先级为:" + Thread.currentThread().getPriority());
      }
  }
}

class B implements Runnable {
  @Override
  public void run() {
      for (int i = 0; i <10 ; i++) {
          System.out.println("B的优先级为:" + Thread.currentThread().getPriority());
      }
  }
}

//结果执行了好几次才出现的结果:
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
A的优先级为:10
B的优先级为:1
A的优先级为:10
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1
B的优先级为:1

这就表示优先级低的线程不是非得优先级高的线程执行完毕之后才执行的,这也可以说明线程就是随机性的!

四、守护线程

守护线程是一种特殊的线程,它属于是一种陪伴线程。简单点说 java 中有两种线程:用户线程和守护线程。可以通过isDaemon()方法来区别它们:如果返回false,则说明该线程是“用户线程”;否则就是“守护线程”。

用户线程一般用于执行用户级任务,而守护线程也就是“后台线程”,一般用来执行后台任务。

需要注意的是:Java虚拟机在“用户线程”都结束后会退出,所以守护线程也会随之结束。注意:主线程main是用户线程。
做一个小例子吧!!!

ublic class TheadTest4 {
   public static void main(String[] args) throws InterruptedException {
       Thread thread1 = new Thread(new A());
       //设置名称为A
       thread1.setName("A...");
       //设置为守护线程
       thread1.setDaemon(true);
       thread1.start();

       Thread thread2 = new Thread(new A());
       //设置名称为B
       thread2.setName("B...");
       thread2.start();
       Thread.sleep(3000);
       //直接中断非守护线程
       thread2.interrupt();
       Thread.sleep(10000);
       System.out.println("程序结束!!!");
   }
}

class A implements Runnable {
   private int i;
   @Override
   public void run() {
       try {
           while (true) {
               i++;
               System.out.println("线程名称:"+Thread.currentThread().getName()+",i=" + i + ",是否为守护线程:" + Thread.currentThread().isDaemon());
               Thread.sleep(1000);
           }
       } catch (InterruptedException e) {
           System.out.println("线程名称:"+Thread.currentThread().getName()+"中断线程了");
       }
   }
}
//结果:
线程名称:A...,i=1,是否为守护线程:true
线程名称:B...,i=1,是否为守护线程:false
线程名称:A...,i=2,是否为守护线程:true
线程名称:B...,i=2,是否为守护线程:false
线程名称:B...,i=3,是否为守护线程:false
线程名称:A...,i=3,是否为守护线程:true
线程名称:B...中断线程了
线程名称:A...,i=4,是否为守护线程:true
线程名称:A...,i=5,是否为守护线程:true
线程名称:A...,i=6,是否为守护线程:true
线程名称:A...,i=7,是否为守护线程:true
线程名称:A...,i=8,是否为守护线程:true
线程名称:A...,i=9,是否为守护线程:true
线程名称:A...,i=10,是否为守护线程:true
线程名称:A...,i=11,是否为守护线程:true
线程名称:A...,i=12,是否为守护线程:true
线程名称:A...,i=13,是否为守护线程:true
程序结束!!!

从上面的代码可以看出来,B是用户线程当它中断了之后守护线程还没有结束,是因为主线程(用户线程)还没有结束,所以说明是所有的用户线程结束之后守护线程才会结束。

五、习题

从以上的例子大家应该还不知道守护线程到底有什么用处!!!所以现在为大家布置一个真实场景的习题。
需求:创建一个用户线程是向一个目录里面存储文件,再启动一个守护线程定时删除这个目录里面创建时间五秒前或者1分钟前创建的文件。

 

赞(1) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » 三、网络编程之线程优先级和守护详解

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏