栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

话说 用户线程&守护线程&线程组&线程优先级

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

话说  用户线程&守护线程&线程组&线程优先级

如果把公司比喻成进程,

那么你和我就是用户线程,

后勤部门就是守护线程(负责给你订水,打扫办公环境等),

每个项目组就是一个线程组,

程序员等级就是优先级(高级程序员 总比初级程序员容易获取资源 概率大 但不是肯定)。

一、 用户线程&守护线程
public static void main(String[] args)   {
 Thread t = new Thread(() -> {
     for (int i = 0; i < 10; i++) {
  try {
      Thread.sleep(1000);
      System.out.println("用户线程");
  } catch (Exception e) {
      e.printStackTrace();
  }
     }
 });

 Thread tdeamon = new Thread(() -> {
     for (int i = 0; i < 100; i++) {
  try {
      Thread.sleep(1000);
      System.out.println("守护线程");
  } catch (Exception e) {
      e.printStackTrace();
  }
     }
 });
 // 设置线程为守护线程   !!必须在start之前设置  否则会报错
 tdeamon.setDaemon(true);

 t.start();
 tdeamon.start();
    }

可以复制执行一下看看,t结束之后,tdeamon虽然没运行够100次但是也就结束了

公司都没有研发、销售、市场等职位了,后勤也就没有必要留着了。

那new Thread() 默认是守护线程还是用户线程 ?

答案: 不确定,要看父线程 新new的线程 默认与父线程一致

1 我们看一下main线程的类型
public class TestDeamon08 {
    public static void main(String[] args)   {
 System.out.println(Thread.currentThread().isDaemon() ? "守护线程":"用户线程");
    }
}
// 输出: 用户线程
2 我们看一下main线程中新建的线程
public static void main(String[] args)   {
 Thread t = new Thread();
 System.out.println(t.isDaemon() ? "t=守护线程":"t=用户线程");
}
// 输出 t=用户线程
3 我们看一下main线程中的线程中的线程
public static void main(String[] args)   {
    new Thread(()->{
 Thread t2 = new Thread();
 System.out.println(t2.isDaemon() ? "t2= 守护线程":"t2=用户线程");
    }).start();
}
输出: t2= 用户线程
4 我们定义一个deamon线程 然后在这个线程中新建一个线程看看 新建的这个线程是不是与父线程一致
public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(() -> {
 System.out.println(Thread.currentThread().isDaemon()? 
      "thread= 守护线程" : "thread=用户线程");
 Thread t3 = new Thread();
 System.out.println(t3.isDaemon() ? "t3= 守护线程" : "t3=用户线程");
    });
    thread.setDaemon(true);
    thread.start();


    Thread.sleep(10000);
}

// 输出:
thread= 守护线程
t3= 守护线程
5 我们看看新建线程是怎么默认daemon的
// 创建线程
Thread thread = new Thread();
// 构造函数  默认名字:Thread-xxx
// 调用init 
public Thread() {
 init(null, null, "Thread-" + nextThreadNum(), 0);
}
// 下边说的线程组ThreadGroup
private void init(ThreadGroup g, Runnable target, String name,
 long stackSize) {
 init(g, target, name, stackSize, null, true);
}
// 主要逻辑
private void init(ThreadGroup g, Runnable target, String name,
 long stackSize, AccessControlContext acc,
 boolean inheritThreadLocals) {
    // 线程名字为null 抛异常杨 
    if (name == null) {
 throw new NullPointerException("name cannot be null");
    }
	// 设置线程名称 
    this.name = name;
	// 获取父线程 
    Thread parent = currentThread();
    // 
    SecurityManager security = System.getSecurityManager();
    // 如果线程分组是null  初始化group 
    // 如果security != null security.getThreadGroup()
    // 如果security == null 就获取父线程的getThreadGroup()
    if (g == null) {
 if (security != null) {
     g = security.getThreadGroup();
 }
 if (g == null) {
     g = parent.getThreadGroup();
 }
    }

   // 一堆代码...
	
    // 设置分组 
    this.group = g;
    // 设置daemon为父daemon !!!
    this.daemon = parent.isDaemon();
    // 设置优先级为父优先级 
    this.priority = parent.getPriority();
    
    // 一堆代码...
}
二、 线程组

在上边代码中我们看到,线程的默认分组是通过security获取的,如果security为null就是用父线程的分组。

1. 我们看看main线程的线程组
public static void main(String[] args) throws InterruptedException {
    System.out.println("main线程组:"+ Thread.currentThread().getThreadGroup().getName());
}
输出: main线程组:main
2. main线程中创建线程 默认分组
public static void main(String[] args)  {
    new Thread(()->{
 System.out.println("线程组:"+Thread.currentThread().getThreadGroup().getName());
    }).start();
}
// 输出:  线程组:main

3. 指定线程分组
public static void main(String[] args)  {
    ThreadGroup t = new ThreadGroup("分组01");
    Thread thread = new Thread(t,()->{
 System.out.println("线程组:"+
      Thread.currentThread().getThreadGroup().getName());
    });
    thread.start();
}
// 输出: 线程组:分组01
4. 指定线程分组 线程中创建线程
public static void main(String[] args)  {
    ThreadGroup t = new ThreadGroup("分组01");
    Thread thread = new Thread(t,()->{
 new Thread(()->{
     System.out.println("线程组:"+
   Thread.currentThread().getThreadGroup().getName());
 }).start();
    });
    thread.start();
}
// 输出: 线程组:分组01
5. 线程组作用

首先 他们表示线程所属 , 比如你操作一个线程的时候,如果他是main线程组的你就过滤掉

期次线程组提供了一些方法来批量操作线程:

    public static void main(String[] args)  {
 ThreadGroup g = new ThreadGroup("分组01");
 Thread thread1= new Thread(g,()->{
     try {
  Thread.sleep(100000);
     } catch (Exception e) {
  System.out.println("线程1异常 结束:"+e.getMessage());
     }
 });
 Thread thread2= new Thread(g,()->{
     try {
  Thread.sleep(100000);
     } catch (Exception e) {
  System.out.println("线程2异常 结束:"+e.getMessage());
     }
 });

 thread1.start();
 thread2.start();

 // 停止所有线程
 // g.stop();
 // 终端所有线程
 // g.interrupt();
 // 还处于活动状态的线程总数
 //System.out.println( g.activeCount());
 // 输出线程组包含线程信息
 //g.list();
 // 获取线程组所有线程的最大优先级
 //int max = g.getMaxPriority();
 // 还有一些其他的 读者阔以自己去看看 了解为主
    }	
三、 优先级

在”一“中我们看源码的时候看到了,优先级默认是获取的父线程的优先级 ,

那main线程优先级是多少呢

public static void main(String[] args) {
    int pro = Thread.currentThread().getPriority();
    System.out.println(pro);
}
// 输出结果: 5 

最大优先级和最小优先级呢 ?

Thread t = new Thread();
t.setPriority(10);
// 看一下setPriority的时候 限制就行了 
public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    // 主要看这句 如果大于MAX_PRIORITY  或者 小于MIN_PRIORITY 就抛异常 
    // 那最大是MAX_PRIORITY 喽  最小是MIN_PRIORITY 喽 
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
 throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
 if (newPriority > g.getMaxPriority()) {
     newPriority = g.getMaxPriority();
 }
 setPriority0(priority = newPriority);
    }
} 
// 揭晓答案 
    
    public final static int MIN_PRIORITY = 1;

   
    public final static int NORM_PRIORITY = 5;

    
    public final static int MAX_PRIORITY = 10;

优先级有什么用呢? 上边说了

线程优先级高了获取cpu的概率高

但是不一定肯定比低优先级的线程先获取到cpu 只是概率高

下边有一个例子测试优先级获取cpu的概率

// 有问题可以关注公众号:木子的昼夜编程  留言会及时回复
public class ProTest02 {
    public static void main(String[] args) throws InterruptedException {
 ThreadGroup g = new ThreadGroup("测试分组");
 // 4个线程  优先级:1 3 5 7
 for (int i = 0; i < 4; i++) {
     String str = String.valueOf("优先级为"+(2*i+1)+"的线程");
     new TP(str,g,2*i+1).start();
 }
 Thread.sleep(3000);
 g.interrupt();

    }
}

class TP extends  Thread{
    AtomicInteger a = new AtomicInteger();
    public  TP(String name,ThreadGroup tg,int pro){
 super(tg,name);
 this.setPriority(pro);

    }
    @Override
    public void run() {
 while (true){
     try {
  Thread.sleep(1);
  a.incrementAndGet();
     }catch (Exception e){
  System.out.println(Thread.currentThread().getName()+"累加:"+a.get());
  break;
     }
 }
    }
}

// 输出结果 (不定)
优先级为5的线程累加:2140
优先级为7的线程累加:2294
优先级为3的线程累加:431
优先级为1的线程累加:139
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号