我是靠谱客的博主 快乐背包,这篇文章主要介绍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.线程初始化

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

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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)内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部