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

【JavaEE】多线程

线程 

在Java中,鼓励多线程编程。进程可以满足并发编程,但是效率不高(创建、销毁、调度时间都比较长,这些都消耗在申请资源上了),而线程就不一样。

线程也叫“轻量级进程”,创建、销毁、调度都更快。但是它不能独立存在,而是依附于进程(也就是说进程包含线程),一个进程可以一个或多个线程,前面谈到的进程调度都是基于一个进程只有一个线程的情况下,实际上一个进程有多个线程,每个线程都是可以独立调度的,每个线程也有状态、优先级、上下文、记账信息,每个PCB对应到每个线程上,pid是与进程共用同一份的(内存指针、文件描述符表也是)。

总的来说就是:进程包含线程-》一个进程由多个PCB共同表示-》每个PCB就用来表示一个线程-》每个线程有自己的状态、优先级、上下文、记账信息-》每个线程都可以独立的去CPU上调度执行-》这些PCB共用了同样的内存指针、文件描述符表-》创建线程/PCB不需要重新申请资源-》创建销毁效率更高

总结线程特点

  1. 每个线程都可以独立的去CPU上调度执行。
  2. 同一个进程的多线程之间共用同一份内存空间、文件资源……(所以创建线程就不需要重新申请资源,直接复用进程的资源,使得线程速度更快)

 

  • 然而不是线程越多效率越快,当增加到一定数目时,效率无法提升,反而会调度线程太多,使调赴花销更大 。
  • 当两个线程同时访问变量时也会出现问题,线程不安全问题。
  •  如果某个线程出现异常:一个线程抛出异常,如果没有妥善处理就容易把整个进程崩溃。

进程与线程的区别(重点) 

  1. 进程包含线程;
  2. 进程和线程都是实现并发并发编程,但是线程比进程更高效、轻量;
  3. 同一个进程的线程之间共用一份资源(内存+硬盘),省去资源的开销;
  4. 进程和进程之间是独立的,线程和线程(同一个进程中)可能会相互影响;
  5. 进程时资源分配的基本单位,线城市调度执行的基本单位; 

多线程 

Java如何进行多线程编程的?

线程是操作系统的概念,操作系统提供一些API可以操作线程,Java针对API进程封装。Thread类就是操作系统提供的API进行封装和抽象。

 1.多线程程序 

public class Test {public static void main(String[] args) throws InterruptedException {Thread t = new MyThread();t.start();while (true){sleep(1000);System.out.println("hello main");}}
}
class MyThread extends Thread{@Overridepublic void run() {while (true) {try {sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("hello thread");}}
}

上面这个程序运行就可以看到,这两个线程是“同时执行”的,看到的结果是两边的日志都在交替打印,---》可以得到的是每个线程都是独立执行的逻辑(独立的执行流)

start可以创建一个新的线程,如果将start改成run,此时代码就不会创建新线程,只有主线程,这个主线程只能执行完run,才能往后继续执行。

上面是使用idea观察多线程,也可以通过 jconsole (jdk-》bin-》jconsole.exe)来观察进程里的多线程,如果不知道jdk安装在哪个路径下可以通过idea寻找。

 然后再双击 jconsole.exe 出现以下页面,,如果没有出现以下页面那就是没有以管理员身份打开

2.创建线程 

1.继承Thread,重写run

1)继承Thread来创建一个线程类;2)创建线程类的实例;3)调用start方法启动线程 

继承Thread类,需要重写它里面的run方法,想要看到“同时”的效果,就需要使用sleep,之前在学C语言中的sleep,现在Thread类中有自己的sleep方法,使用Thread中的sleep会出现异常,需要解决异常可以抛出异常或者try/catch异常,如果是重写父类的run方法,父类的run方法没有throws,子类方法也就不能有,所以只能try/catch异常。main方法中就可以使用throws也可以使用try/catch。操作系统对于多个线程的调度顺序是不确定的/“随机的”,运行结果取决于操作系统对线程调度的模块(调度器)

2.实现Runnable,重写run 

1)实现Runable接口;2)创建Thread类实例,调用Thread的构造方法是将Runable对象作为target参数;3)调用start方法; 

使用Runnable 的写法,和直接继承Thread 之间的区别就是解耦合(两个线程之间的关联程度)

 

3. 继承Thread,重写run(使用匿名内部类)

 使用匿名内部类创建Thread子类对象

4.实现Runnable,重写run(使用匿名内部类)

 使用匿名内部类创建Runnable子类对象

5.基于 lambda 表达式(推荐使用) 

lambda表达式中直接重写run方法中的内容,不用再继承实现哪个类或者哪个接口。 

3.Thread 的其他构造方法

Thread()//创建线程对象

Thread(Runnable target)//使用Runnable对象创建线程对象

Thread(String name)//创建线程对象,并命名

Thread(Runnable target, String name) //使用Runnable对象创建线程对象,并命名

4.Thread 常见的属性

ID//身份标识     getId()//获取id

名称                  getName()//获得线程名称

状态                  getState()//获得当前状态

优先级              getPriority()

是否后台线程    isDaemon()

是否存活           isAlive()

是否被中断       isInterrupted()

后台线程:后台进程不结束不影响整个进程的结束。

前台线程:如果前台线程没有执行结束,此时整个进程是一定不会结束的。

Thread 对象往往比系统中的线程更长,线程没了Thread 对象还在。

http://www.xdnf.cn/news/7497.html

相关文章:

  • Java转Go日记(四十一):Gorm删除
  • Java大师成长计划之第28天:处理多线程的Web应用
  • 嵌入式学习笔记 - CAN总线
  • 房贷利率计算前端小程序
  • 图论学习笔记 3
  • 电磁感应在量子计算中如何应用
  • Adv. Sci.|南医大倪春辉团队破局肺纤维化:锁定脂肪酸氧化与糖酵解 “失衡点”,挖掘关键治疗靶点
  • python宠物用品商城系统
  • 深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧
  • 【Java的批量操作】
  • 【leetcode】59. 斐波那契数
  • RK3568 OH5.1 源码编译及问题
  • 海康威视摄像头C#开发指南:从SDK对接到安全增强与高并发优化
  • React+TypeScript多步骤表单:告别表单地狱的现代解决方案
  • 请问交换机和路由器的区别?vlan 和 VPN 是什么?
  • Python + moviepy:根据图片或数据高效生成视频全流程详解
  • 链表的面试题8之环形链表
  • 关闭 Ubuntu 20.04 的 GNOME Shell和PulseAudio
  • Java 03(代码块,内部类,lambda表达式)
  • python八股文汇总(持续更新版)
  • 《医院运营管理典型应用数据资源建设指南2025》全面分析
  • Apache Apisix配置ip-restriction插件以限制IP地址访问
  • CesiumEarth v1.15 更新
  • 在Windows系统中使用C++与Orthanc交互:基于DICOMweb的医学影像应用开发
  • Fiddler抓包教程->HTTP和HTTPS基础知识
  • 八股文--JVM(2)
  • Python 计算机网络TCP网络应用程序开发
  • 解决npm install报错:getaddrinfo ENOTFOUND registry.nlark.com
  • 数据分析_商务运营考核指标体系搭建
  • AI筑基,新质跃升|英码科技亮相华为广东新质生产力创新峰会,发布大模型一体机新品,助力产业智能化转型