首页 > 编程知识 正文

多线程和并发(一个进程可以有多个线程)

时间:2023-05-04 14:44:30 阅读:103347 作者:2636

认识java里的线程

Java程序本来就是多线程的。

一个Java程序从main()方法开始,按照建立的代码逻辑执行。看似没有其他线程参与,但实际上,Java程序本身就是多线程的,因为main()方法是由一个名为main的线程执行的。

[6]监控Ctrl-Break //监控Ctrl-Break的中断信号

[5]附加监听器//内存转储、线程转储、类信息统计、获取系统属性等。

[4]信号调度器//分发处理发送到JVM的信号的线程。

[3]终结器//调用对象的终结方法的线程

[2]引用处理程序//清除引用线程

[1]主//主线程,用户程序入口

00-1010启动

启动线程有几种方法:

1,X扩展线程,然后X开始

2.x实现Runnable,然后交给Thread运行。

线程和可运行的区别

线程是Java中线程的唯一抽象。Runnable只是任务或业务逻辑的抽象。线程可以接受Runnable的任何实例并执行它。

停止

螺纹的自然终止

执行在运行完成后终止,或者在执行过程中引发未处理的异常,导致线程过早终止。

停止

挂起、恢复和停止操作对应的线程的API是挂起()、恢复()和停止()。目前这些API已经过期,不再推荐使用。主要原因如下:以suspend()方法为例。调用后,线程不会释放被占用的资源(如锁),而是会占用资源进入睡眠状态,容易导致死锁。同样,stop()方法在终止一个线程时,也不会保证线程资源的正常释放,通常也不会给线程完成资源释放工作的机会,所以程序可能会在不确定的状态下工作。由于suspend()、resume()和stop()方法的副作用,这些方法被标记为不推荐使用的过时方法。

暂停

假设已有线程A,如何安全中止?

其他线程B调用线程A的interrupt()方法来中断它。中断就像另一个线程跟线程打招呼,“A,你要中断了”,但不代表线程A会立即停止工作。相反,线程甚至可以忽略这个中断请求。因为java中的线程是协作的,而不是抢占式的。线程通过检查其中断标志是否设置为真来响应。线程使用方法isInterrupted()判断是否中断,或者调用静态方法Thread.interrupted()判断当前行是否中断,但Thread.interrupted()会同时将中断标志重写为false。

如果线程处于阻塞状态(如线程调用thread.sleep、thread.join、thread.wait等。),如果线程在检查中断标志时发现中断标志为真,会在这些阻塞方法调用时抛出一个Interrupted Exception,抛出异常后立即清除线程的中断标志位,即复位为false。

不建议自定义取消标志位来停止线程运行。因为当run方法中有阻塞调用时,无法快速检测到cancel标志,所以线程在从阻塞调用返回之前不会检查cancel标志。在这种情况下,最好使用中断。

因为一般的阻塞方法,如睡眠,支持中断检查,检查中断位的状态和检查取消标志位没有区别。使用中断位的状态还可以避免声明取消标志位,并减少资源消耗。

注意:处于死锁状态的线程不能被中断。

00-1010了解运行()和启动()

线程类是Java中线程概念的抽象。可以这样理解:其实通过new Thread(),它只是一个来自new的Thread实例,并没有和操作系统中的真实线程挂钩。只有执行start()方法后,才能实现真正的启动线程。

start()方法允许线程进入就绪队列等待cpu分配,然后在cpu分配后调用实现的run()方法。start()方法不能重复调用,如果重复调用,将引发异常。

run方法是实现业务逻辑的地方,本质上和任何类的任何成员方法一样,可以重复执行,也可以单独调用。

的其他线程相关方法

产量法

Yield()使当前线程放弃对CPU的占有,但放弃的时间是不可设置的,不会释放锁资源。

注意:执行yield()的线程不一定持有锁。如果有,它可以在释放锁后调用yield()方法。

执行yi

eld()的线程有可能在进入到就绪状态后,会被操作系统再次选中,马上又被执行。

wait()/notify()/notifyAll()后面单独讲述

join 方法

把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行。

如在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续执行线程 B。

线程的优先级

在 Java 线程中,通过一个整型成员变量 priority 来控制优先级,优先级的范围从 1~10,在线程构建的时候可以通过 setPriority(int)方法来修改优先级,默认优先级是 5,优先级高的线程分配时间片的数量要多于优先级低的线程。

设置线程优先级时,针对频繁阻塞(休眠或者 I/O 操作)的线程需要设置较高优先级,而偏重计算(需要较多 CPU 时间或者偏运算)的线程则设置较低的优先级,确保处理器不会被独占。在不同的 JVM 以及操作系统上,线程规划会存在差异,有些操作系统甚至会忽略对线程优先级的设定。

守护线程

Daemon(守护)线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。这意味着,当一个 Java 虚拟机中不存在非 Daemon 线程的时候,Java 虚拟机将会退出。

可以通过调用 Thread.setDaemon(true)将线程设置为 Daemon 线程。一般情况下用不上,比如垃圾回收线程就是 Daemon 线程。

注意:在构建 Daemon 线程时,不能依靠 finally 块中的内容来确保执行关闭或清理资源的逻辑。当java虚拟机不存在非Daemon线程时,虚拟机会直接退出,此时 Daemon 线程中的 finally 将不会执行。

小伙伴们,多多关注,需要鼓励!接下来会持续分享并发编程进阶、JVM性能深度调优、网络编程与高效IO、深入Tomcat底层、Mysql深度优化、架构基础必备Linux等相关知识。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。