zoukankan      html  css  js  c++  java
  • 并发编程学习笔记(四、线程的优先级)

    目录:

    • 线程优先级
    • 线程优先级的特性
    • 守护线程
    • 总结

    线程优先级:

    1、在java中线程优先级的范围是1~10,默认为5,数值越大优先级越高。

    2、高优先级线程的执行会优先于低优先级的线程,但也仅仅只是优先执行而已。

    线程优先级的特性:

    1、继承性

    线程A中执行了线程B,那么线程B有着和线程A同样的优先级

     1 public class MyThread1 extends Thread {
     2     @Override
     3     public void run() {
     4         // 输出线程级别
     5         System.out.println("MyThread1 Priority = " + this.getPriority());
     6         // 启动线程MyThread2
     7         MyThread2 myThread2 = new MyThread2();
     8         myThread2.start();
     9     }
    10 }
    1 public class MyThread2 extends Thread {
    2     @Override
    3     public void run() {
    4         System.out.println("MyThread2 Priority = " + this.getPriority());
    5     }
    6 }
    1 public class ThreadPriority {
    2     public static void main(String[] args) {
    3         System.out.println("once Main Thread Priority = " + Thread.currentThread().getPriority());
    4         Thread.currentThread().setPriority(10);
    5         System.out.println("twice Main Thread Priority = " + Thread.currentThread().getPriority());
    6         MyThread1 myThread1 = new MyThread1();
    7         myThread1.start();
    8     }
    9 }

    注释ThreadPriority类第4、5行,则结果为:

    once Main Thread Priority = 5

    twice Main Thread Priority = 5

    MyThread1 Priority = 5

    MyThread2 Priority = 5

    因为线程优先级默认为5

    ———————————————————————————————————————————————————————

    正常执行ThreadPriority的main方法,则结果为:

    once Main Thread Priority = 5

    twice Main Thread Priority = 10

    MyThread1 Priority = 10

    MyThread2 Priority = 10

    从结果可以看出线程具有继承性。

    2、规则性和随机性

    • CPU尽量将资源给优先级高的线程,但并不是优先级高的线程先执行完
    • 即使线程没有设置优先级,也不能保证线程运行的先后,线程的运行具有随机性。
     1 public class MyThread1 extends Thread {
     2     @Override
     3     public void run() {
     4         long start = System.currentTimeMillis();
     5         System.out.println("------1------ thread 1 start running");
     6         long count = 0;
     7         for (int i = 0; i < 10; i++) {
     8             for (int j = 0; j < 50000; j++) {
     9                 Random random = new Random();
    10                 random.nextInt();
    11                 count = count + i;
    12             }
    13         }
    14         long end = System.currentTimeMillis();
    15         System.out.println("------1------ thread 1 use time = " + (end - start));
    16     }
    17 }
     1 public class MyThread2 extends Thread {
     2     @Override
     3     public void run() {
     4         long start = System.currentTimeMillis();
     5         System.out.println("------2------ thread 2 start running");
     6         long count = 0;
     7         for (int i = 0; i < 10; i++) {
     8             for (int j = 0; j < 50000; j++) {
     9                 Random random = new Random();
    10                 random.nextInt();
    11                 count = count + i;
    12             }
    13         }
    14         long end = System.currentTimeMillis();
    15         System.out.println("------2------ thread 2 use time = " + (end - start));
    16     }
    17 }
     1 public class ThreadPriority {
     2     public static void main(String[] args) {
     3         for (int i = 0; i < 10; i++) {
     4             MyThread1 myThread1 = new MyThread1();
     5             myThread1.setPriority(1);
     6             MyThread2 myThread2 = new MyThread2();
     7             myThread2.setPriority(10);
     8             myThread1.start();
     9             myThread2.start();
    10         }
    11     }
    12 }

    运行结果:(过多,文章就不展示了 !!!∑(゚Д゚ノ)ノ)

    从结果便可以看出优先级高的线程2并不是一定比线程1先执行完。

    守护线程:

    • 线程分为两种,一种是开发人员创建的线程,此类线程一般叫做用户线程;一种是JVM后台线程,这类线程一般叫做守护线程如垃圾回收线程
    • 通过isDaemon()方法可以区分是否为守护线程,函数返回true则为守护线程,反之为用户线程。
    • 用户线程执行完后JVM便会结束程序,因为守护线程是后台线程,当用户线程全执行完后便没有需要守护的东西了。
    • 可以通过Thread.setDaemon()设置线程为守护线程,但需要在执行start()方法前指定,否则会抛出IllegalThreadStateException异常。
     1 public class CommonThread extends Thread {
     2     @Override
     3     public void run() {
     4         for (int i = 0; i < 5; i++) {
     5             System.out.println("用户线程第" + i + "次执行!");
     6             try {
     7                 Thread.sleep(10);
     8             } catch (Exception e) {
     9                 e.printStackTrace();
    10             }
    11         }
    12     }
    13 }
     1 public class MyDaemon implements Runnable {
     2     @Override
     3     public void run() {
     4         for (long i = 0; i < 100; i++) {
     5             System.out.println("守护线程第" + i + "次执行!");
     6             try {
     7                 Thread.sleep(10);
     8             } catch (Exception e) {
     9                 e.printStackTrace();
    10             }
    11         }
    12     }
    13 }
     1 public class DaemonThreadDemo {
     2     public static void main(String[] args) {
     3         Thread t1 = new CommonThread();
     4         Thread t2 = new Thread(new MyDaemon());
     5         // 设置为守护线程
     6         t2.setDaemon(true);
     7         t2.start();
     8         t1.start();
     9     }
    10 }

    运行结果:

    用户线程第0次执行!

    守护线程第0次执行!

    守护线程第1次执行!

    用户线程第1次执行!

    用户线程第2次执行!

    守护线程第2次执行!

    守护线程第3次执行!

    用户线程第3次执行!

    用户线程第4次执行!

    守护线程第4次执行!

    守护线程第5次执行!

    守护线程应该是需要执行100次的,但实际上仅执行了6次,所以我们可以得知用户线程执行完后JVM会停止程序,守护线程也就不会执行下去了。

    总结:

    1、线程有优先级之分,从1到10。

    2、优先级高的线程尽量比优先级低的线程先运行 。

    3、线程优先级的特性:继承性、规则性、随机性

    4、Java中线程分为2种:用户线程和守护线程。

    5、守护线程在JVM中所有用户线程都结束后退出。

    6、用户可以手动创建守护线程。

  • 相关阅读:
    微服务
    flume
    mongodb
    Java 代理学习笔记
    HttpClient连接池
    一起写RPC
    spring boot cloud
    .NET MVC 表主外键关系 JSON 无限循环 方案二(推荐)
    EF提示“序列化类型为XXX的对象时检测到循环引用”
    Handlebars.js registerHelper
  • 原文地址:https://www.cnblogs.com/bzfsdr/p/11566593.html
Copyright © 2011-2022 走看看