多线程学习三,线程的分类

多线程学习三,线程的分类,第1张

线程学习三,线程的分类 多线程学习三,线程的分类:主线程、守护线程、子线程

文章目录

多线程学习三,线程的分类:主线程、守护线程、子线程总结

1. 主线程2. 精灵线程3. 线程优先级

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
思维导图:

1. 主线程

由main线程启动的就是主线程

那么在Java中一个类里只有一个线程吗?不是的,Java天生就是多线程的,即使在一个简单的Hello World程序中也会有很多线程的产生。

2. 精灵线程

在Java中,线程可以简单分为两种类型:用户线程(User Thread)、守护线程(Daemon Thread)。在一个Java程序中,任何一个守护线程都是整个JVM中所有非守护线程的保姆:

只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。

下面我们来举一个用户线程退出,守护线程被迫结束的例子:

这里值得注意的是,需要先开启用户线程再开启子线程

public class _9_daemon {
    public static void main(String[] args) {
        Thread t1=new CommonThread();
        //新建任务、再绑定到一个线程上
        Thread t2 = new Thread(new MyDaemon());
        //将t2设置为守护线程
        t2.setDaemon(true);
        //正确做法,线程运行前设置守护线程
        t2.start();
        t1.start();
    }
}
//自定义线程,继承自Thread
class CommonThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("用户线程第"+i+"此执行");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//任务类
class MyDaemon implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("用户线程第"+i+"此执行");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

从运行结果可以看到,当用户线程退出后,守护线程也自动退出了

守护线程第0此执行
用户线程第0此执行
守护线程第1此执行
用户线程第1此执行
用户线程第2此执行
守护线程第2此执行
守护线程第3此执行
用户线程第3此执行
守护线程第4此执行
用户线程第4此执行
守护线程第5此执行
3. 线程优先级

我们可以通过设置线程的优先级来控制线程的执行顺序,但是我们并不能精准控制,到底是谁先运行,这其实是一件概率事件,并不能确定,举个栗子:

public class _10_Priority {
    public static void main(String[] args) {
        ShowTime task = new ShowTime();
        Thread t1 = new Thread(task,"线程一");
        //设置线程的优先级
        t1.setPriority(1);
        t1.start();

        Thread t2 = new Thread(task, "线程二");
        t2.setPriority(10);
        t2.start();
    }
}

class ShowTime implements Runnable{
    @Override
    public void run() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        while (true){
            System.out.println(Thread.currentThread().getName()+"当前的时间为:"+sdf.format(System.currentTimeMillis()));
            try {
            	Thread.sleep(1000);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    }
}

我们来看一下打印的结果:

线程一当前的时间为:2022年01月27日 02:15:55
线程二当前的时间为:2022年01月27日 02:15:55
线程一当前的时间为:2022年01月27日 02:15:56
线程二当前的时间为:2022年01月27日 02:15:56
线程一当前的时间为:2022年01月27日 02:15:57
线程二当前的时间为:2022年01月27日 02:15:57
线程二当前的时间为:2022年01月27日 02:15:58
线程一当前的时间为:2022年01月27日 02:15:58
线程二当前的时间为:2022年01月27日 02:15:59
线程一当前的时间为:2022年01月27日 02:15:59
线程一当前的时间为:2022年01月27日 02:16:00
线程二当前的时间为:2022年01月27日 02:16:00

可以看到并没有严格遵循,这只是一件概率上的事情。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5719900.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存