当前位置: 首页 > article >正文

Java线程详解

线程是CPU调度和分配的基本单位,是操作系统可以识别的最小执行和调度单位,每个线程都有自己特定的独立的内存区域,当然也与其他线程共享堆内存,文件队列以及其他内核资源,Java虚拟机允许一个应用拥有多个线程并发工作。

每个线程都有优先级,高优先级的线程会优先于低优先级的线程执行。当不特别指定线程优先级时,新创建的线程优先级与发起创建操作线程的优先级一致,对于守护线程创建的线程而言,其也会被视作守护线程

守护线程指的是专门为了服务其他线程而创建的线程,比如垃圾回收线程,就是最典型的守护线程,当所有非守护线程都执行完毕时(包括主线程),此时JVM退出,进而守护线程也就停止运行了。

守护线程中不能持有需要关闭的资源,如文件,数据库等,当JVM退出时,守护线程没有机会执行关闭操作,极有可能丢失数据。

对于JVM而言,所有非守护线程都执行完毕时,无论有没有守护线程在运行,虚拟机都会自动退出。

JVM自动退出的情况

  1. 调用Runtime类的exit方法并且安全管理器允许进行退出操作时
  2. 所有的非守护线程都执行完毕时

线程创建方式

在Java中,有两种手动创建线程方式:

  1. 继承Thread类
  2. 使用Runnable类(也可以使用FutureTask+Callable或Runnable,但本质仍是Runnable的实现方式,FutureTask的顶级父类是Runnable)

继承Thread示例代码如下:

// 继承Thread类,在run方法中实现需要运行在线程中的逻辑
class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
 }

// 启动线程运行
PrimeThread p = new PrimeThread(143);
p.start();

使用Runnable示例代码如下:

// 实现runnable类
class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
}

//  启动线程运行
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

这里说的是手动创建两种方式,意思是开发者直接接触到Thread对象,需要自主控制Thread的运行停止等,在java中也有一些自动创建线程的并发工具,比如线程池(ExecutorService)等

线程状态切换

1-4-1-1

如上图所示,线程主要有初始,可运行,运行,等待/阻塞,终止五种状态。当线程获取到CPU时间片切为可运行状态时,就会从可运行状态切入运行状态。线程运行中,如果遇到了同步锁时,等待获取资源则会切入阻塞状态,获取到资源后再从阻塞状态切入运行状态,超时等待状态和等待状态切入切出与此类似。

线程常见接口说明

接口名接口说明备注
start开始执行该线程,表示该线程从初始状态进入可运行状态,当分配到CPU时间片后,就会进入运行状态/
stop强制结束该线程执行,表示线程从运行状态进入终止状态,已弃用/
yield当前线程释放CPU时间片,由运行状态进入可运行状态,让系统重新选择线程执行,有可能继续执行,也有可能等待/
join在当前线程,调用其他线程的join方法,则当前线程阻塞,直到其他线程执行完后,该线程继续执行,可选择指定最长阻塞时间,单位毫秒/
interrupt标记线程中断状态,并不等于该线程停止运行。如果当前线程处于阻塞状态,执行interrupt方法会抛出异常,可以尝试在异常内跳出run方法执行以终止线程/
setDaemon设置当前线程是否是守护线程,true-守护线程,false-不是守护线程/
setPriority设置线程优先级,传入的值在1-10之间,数值越大,优先级越高,默认优先级为5/
sleepThread类的static方法,让调用线程进入休眠状态,当线程持锁时,sleep不会导致锁匙放,只会释放CPU资源,sleep状态的线程不可以被唤醒/
wait使线程进入等待状态,线程在等待状态时会释放所持有的monitor锁,处于wait状态的线程可以通过notify或者notifyAll唤醒/

!!!易错点

t为Thread对象,调用t.sleep()并不一定是让线程t进入休眠状态,是让执行t.sleep()这段代码的线程进入休眠状态,所有要让线程休眠,必须在该线程内部执行Thread.sleep()

停止线程的方式

一般情况下,我们可以通过如下方式停止线程:

  1. 使用标志位,在标志位为true时跳出执行以结束线程
  2. 使用interrupt方法,在run方法中判断中断状态结束线程执行
  3. 使用stop方法强制停止线程,不推荐

http://www.kler.cn/a/14672.html

相关文章:

  • 【飞腾】遇到的问题与解决办法
  • SS524V100 RTL8152B(USB转网卡)驱动移植
  • 【Java基础】使用Java 8的Stream API来简化Map集合的操作
  • 【LeetCode: 5. 最长回文子串 | 暴力递归=>记忆化搜索=>动态规划 => 中心扩展法】
  • C/C++占位符,%x和%p的区别
  • 和chatgpt学习javascript,第一天,学习背景知识
  • 电源电压监测(SVD)
  • SpringBoot整合ELK做日志(超完整)
  • AR实战-基于Krpano的多场景融合及热点自定义
  • 基于Stackelberg博弈的光伏用户群优化定价模型(Matlab代码实现)
  • 什么是矩阵式项目管理?
  • Go | 一分钟掌握Go | 3 - 学习路线
  • 华为OD机试真题(Java),开元音统计(100%通过+复盘思路)
  • 介绍与评测Intel HLE与RTM技术
  • 如何用链表实现LRU缓存淘汰算法
  • 【android专题】学习android,第一天学习:软件和组件了解
  • AI | 浅谈AI技术以及其今后发展
  • 随机模型预测控制(SMPC)——考虑概率约束(Matlab代码实现)
  • 业内首批!安全狗入选Gartner《云原生应用保护平台市场指南》报告
  • 【小技巧】word文档编辑技巧(一)