乐趣区

关于java:话说-用户线程守护线程线程组线程优先级

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

如果把公司比喻成过程,

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

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

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

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

一、用户线程 & 守护线程
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

有问题能够留言哦,或公众号留言(回复快):

退出移动版