我是靠谱客的博主 快乐背包,最近开发中收集的这篇文章主要介绍java并发原理实战(3) -- 线程的中断和初始化1.多线程中start和run方法的区别?2.Thread.currentThread()与this的区别3.后台进程setDaemon有啥用4.线程的中断5.暂停线程(不推荐使用)6.线程初始化,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

线程的中断和初始化

  • 1.多线程中start和run方法的区别?
  • 2.Thread.currentThread()与this的区别
  • 3.后台进程setDaemon有啥用
  • 4.线程的中断
    • ①暴力停止stop(不建议使用)
    • 为啥不推荐:
    • ②通过中断标志中断(推荐)
    • ③中断线程推荐写法:使用三个反人类的方法+抛出异常方方式
  • 5.暂停线程(不推荐使用)
    • ①独占资源:
    • ②不同步
  • 6.线程初始化

1.多线程中start和run方法的区别?

参考链接:

https://www.cnblogs.com/zhaosq/p/10564698.html

start源码:
在这里插入图片描述

1。start():

​ 先来看看Java API中对于该方法的介绍:

​ 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

​ 结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

​ 多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体中的代码执行完毕而直接继续执行后续的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里的run()方法 称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

2。run():

同样先看看Java API中对该方法的介绍:

​ 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

Thread 的子类应该重写该方法。

run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

3。总结:

调用start方法方可启动线程,而run方法只是thread类中的一个普通方法调用,还是在主线程里执行。

2.Thread.currentThread()与this的区别

参考链接:

https://www.cnblogs.com/zjm-1/p/9513398.html

在自定义线程类时,如果线程类是继承java.lang.Thread的话,那么线程类就可以使用this关键字去调用继承自父类Thread的方法,this就是当前的对象。

另一方面,Thread.currentThread()可以获取当前线程的引用,一般都是在没有线程对象又需要获得线程信息时通过Thread.currentThread()获取当前代码段所在线程的引用。

3.后台进程setDaemon有啥用

设置守护线程 其他线程执行完,即使他自己没有执行完,他也会退出

演示1:
在这里插入图片描述
在这里插入图片描述

运行结果:
在这里插入图片描述

把demo2的代码放开:
在这里插入图片描述

看下结果:
在这里插入图片描述

结果显示: 一直在执行,说明一个问题。demo1守护着demo2在运行,如果没有别的线程在运行他也得死掉。这保镖很敬业!!

4.线程的中断

①暴力停止stop(不建议使用)

在这里插入图片描述

2秒后,线程停止:

在这里插入图片描述

为啥不推荐:

原因:

①:直接给退出线程了,那我一直用的资源得不到释放
​ ②:释放锁,造成数据不一致。

  • 原因1示例:
    在这里插入图片描述
    在这里插入图片描述

  • 原因二实例:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

②通过中断标志中断(推荐)

这里java设计的api,三个反人类的方法:

在这里插入图片描述

傻傻分不清楚:

  • interrupt(): 实例对象方法
    在这里插入图片描述

  • interrupted 静态方法: 这相当于一个 测试方法,测试一下,当前的线程是 中断的线程吗?测试完事后,将当前行线程的中断标志改为false。
    在这里插入图片描述
    在这里插入图片描述

  • isInterrupted

isTnterrupted:普通方法,也是一个测试方法,看下调用的对象是中断了吗?和上面不同的是,他不清除中断标志。原来中断标志是啥还是啥。

在这里插入图片描述

③中断线程推荐写法:使用三个反人类的方法+抛出异常方方式

代码演示:
在这里插入图片描述
运行结果:
在这里插入图片描述

说明: 线程1被清除了。

这算是中断线程最好的方式,更多可以看下《java多线程核心技术》这本书,里面还有沉睡的线程停止,异常方法停止也就是现在说的,还有3个反人类方法+return方式,但是最好的这里说了。

5.暂停线程(不推荐使用)

过时的方法,不说也可以,但是看到以前的代码还是需要了解下的:
在这里插入图片描述

不推荐使用的原因:

①独占资源:

在这里插入图片描述

  • 独占资源的情况1:
    在这里插入图片描述
    在这里插入图片描述

运行结果:
在这里插入图片描述

  • 独占资源的情况2(使用print的时候):
    在这里插入图片描述

结果显示:没问题,线程被暂停了,没机会执行了,main方法退出了也就。接下来,变下
在这里插入图片描述
在这里插入图片描述

②不同步

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.线程初始化

看下线程的几个构造方法
在这里插入图片描述

点看会看到
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

 private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();

        /*
         * Do we have the required permissions?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();

        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

全部调用的都是init方法,干了啥呢?

1)创建你的线程,就是你的父线程
2)默认的ThreadGroup就是父线程的ThreadGroup
3)默认的daemon状态是父线程的daemon状态
4)默认的优先级是父线程的优先级
5)默认的线程名称是Thread-X的形式
6)线程id是从1开始的全局递增。


最后

以上就是快乐背包为你收集整理的java并发原理实战(3) -- 线程的中断和初始化1.多线程中start和run方法的区别?2.Thread.currentThread()与this的区别3.后台进程setDaemon有啥用4.线程的中断5.暂停线程(不推荐使用)6.线程初始化的全部内容,希望文章能够帮你解决java并发原理实战(3) -- 线程的中断和初始化1.多线程中start和run方法的区别?2.Thread.currentThread()与this的区别3.后台进程setDaemon有啥用4.线程的中断5.暂停线程(不推荐使用)6.线程初始化所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部