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

Java基础 Day24

一、进程和线程

1、进程

(1)概念

进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动

是系统进行资源分配的基本单位

简单理解:程序的执行过程(正在运行的应用程序)

(2)特性

独立性:每一个进程都有自己的空间,在没有经过进程本身允许的情况下,一个进程不可以直接访问其它的的进程空间

动态性:进程是动态产生,动态消亡的

并发性:任何进程都可以同其它进程一起并发执行

Tips:

并行:在同一时刻,有多个指令在多个CPU上【同时】执行

并发:在同一时刻,有多个指令在单个CPU上【交替】执行

多进程同时工作:对于一个CPU(单核),它是在多个进程间轮换执行的

2、线程

(1)概念

线程(Thread):进程可以同时执行多个任务,每个任务就是线程

(2)多线程的意义

提高执行效率;同时处理多个任务

随着处理器上的核心数量越来越多,现在大多数计算机都比以往更加擅长并行计算

但是,一个线程,在一个时刻,只能运行在一个处理器核心上

Java程序也是一个进程,如果是一个单线程程序,则无法调动处理器的多个核心

二、Java中开启线程的方式

Tips:Java程序默认是多线程的,一条主线程,一条垃圾回收线程

1、法一:继承Thread类

步骤:

(1)编写一个类继承Thread类

(2)重写run方法

(3)将线程任务写在run方法中

(4)创建线程对象

(5)调用start方法开启线程

注意:直接调用run方法并不能开启线程

2、法二:实现Runnable接口

(扩展性更好)

步骤:

(1)编写一个类实现Runnable接口

(2)重写run方法

(3)将线程任务写在run方法中

(4)创建线程任务资源对象

(5)创建线程对象,将资源传入

(6)使用线程对象调用start方法开启线程

public class ThreadDemo2 {public static void main(String[] args) {
//        (4)创建线程任务资源对象MyRunnable mr = new MyRunnable();
//        (5)创建线程对象,将资源传入Thread t1 = new Thread(mr);
//        (6)使用线程对象调用start方法开启线程t1.start();for (int i = 0; i < 100; i++) {System.out.println("main" + i);}}
}//(1)编写一个类实现Runnable接口
class MyRunnable implements Runnable {
//    (2)重写run方法@Overridepublic void run() {
//        (3)将线程任务写在run方法中for (int i = 0; i < 100; i++) {System.out.println("MyRunnable" + i);}}
}

3、法三:实现Callable接口

(线程任务有返回值)

步骤:

(1)编写一个类实现Callable接口

(2)重写call方法

(3)将线程任务写在call方法中

(4)创建线程任务资源对象

(5)创建线程任务对象,封装线程资源

(6)创建线程对象,传入线程任务

(7)使用线程对象调用start方法开启线程

public class ThreadDemo3 {public static void main(String[] args) throws ExecutionException, InterruptedException {MyCallable mc = new MyCallable();FutureTask<Integer> task = new FutureTask<>(mc);Thread thread = new Thread(task);thread.start();Integer result = task.get(); // 获取线程任务的返回值System.out.println(result);}
}class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i <= 100; i++) {sum += i;}return sum;}
}

三、线程的相关方法

String getName​()

返回此线程的名称

void setName​(String name)

设置线程的名字(构造方法也可以设置名字)

static Thread currentThread()

获取当前线程的对象

static void sleep(long time)

让线程休眠指定的时间,单位为毫秒

setPriority(int newPriority)

设置线程的优先级,从1到10,默认为5

final int getPriority()

获取线程的优先级

final void setDaemon(boolean on)

设置为守护线程

Tips:线程的调度方式分为抢占式调度(随机)和非抢占式调度(轮流)

Java 采用的方式是抢占式调度

提高线程的优先级可以提高该线程抢到CPU的概率

四、线程安全和同步

1、安全问题出现的条件

是多线程环境

有共享数据

有多条语句操作共享数据

2、同步技术

将多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程可以执行

(1)同步代码块

格式:
synchronized(锁对象) {多条语句操作共享数据的代码
}示例:
public class TicketDemo {public static void main(String[] args) {// 只new了一个TicketTask对象,三个线程共享一份数据TicketTask ticket = new TicketTask();Thread t1 = new Thread(ticket);Thread t2 = new Thread(ticket);Thread t3 = new Thread(ticket);t1.start();t2.start();t3.start();}
}class TicketTask implements Runnable {private int tickets = 2000;@Overridepublic void run() {while (true) {// 建议使用字节码文件作为锁对象synchronized (TicketTask.class) {if (tickets <= 0) {break;}System.out.println(Thread.currentThread().getName() + " sold " + tickets);tickets--;}}}
}   

Tips:锁对象可以是任意对象,但是需要保证多条线程的锁对象,是同一把锁

同步可以解决多线程的数据安全问题,但是也会降低程序的运行效率

(2)同步方法

在方法的返回值类型前面加入 synchronized 关键字

该方法里的代码就变成同步的

静态方法的锁对象是字节码对象,非静态方法的锁对象是 this

(3)Lock 锁

使用 Lock 锁,可以更清晰地看到哪里加了锁,哪里释放了锁

Lock 是接口,无法直接创建对象

public ReentrantLock()

构造方法:创建一个 ReentrantLock 的实例互斥锁

void lock()

加锁

void unlock();

释放锁

3、死锁

两个或者多个线程互相持有对方所需要的资源

导致这些线程处于等待状态,无法前往执行

产生死锁的情况:同步嵌套

http://www.lryc.cn/news/2391682.html

相关文章:

  • 提问:鲜羊奶是解决育儿Bug的补丁吗?
  • 关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别
  • Hive 分桶(Bucketing)深度解析:原理、实战与核心概念对比
  • 网络协议DHCP
  • 什么是可重组机器人?
  • 4、docker compose
  • Node.js全局对象详解:console、process与核心功能
  • 测试策略:AI模型接口的单元测试与稳定性测试
  • SQL里几种JOIN连接
  • 基于通义千问的儿童陪伴学习和成长的智能应用架构。
  • 生产环境Mysql推荐配置参数
  • LVS-DR 负载均衡群集
  • 理解并解决高丢包率问题,构建清晰流畅的实时音视频通话
  • Ubuntu系统Todesk进度卡在100%
  • [Dify] 如何应对明道云API数据过长带来的Token超限问题
  • Axure动态面板学习笔记
  • eNSP企业综合网络设计拓扑图
  • 工程化架构设计:Monorepo 实战与现代化前端工程体系构建
  • BugKu Web渗透之备份是个好习惯
  • 华为AP6050DN无线接入点瘦模式转胖模式
  • uniapp 配置本地 https 开发环境(基于 Vue2 的 uniapp)
  • 十、【核心功能篇】项目与模块管理:前端页面开发与后端 API 联调实战
  • 【大模型/MCP】MCP简介
  • [Godot][游戏开发] 如何在 Godot 中配置 Android 环境(适配新版 Android Studio)
  • Vue-Router中的三种路由历史模式详解
  • 机器学习多分类逻辑回归和二分类神经网络实践
  • 社交类网站设计:经典feed流系统架构详细设计(小红书微博等)
  • K6 是什么
  • RISC-V PMA、PMP机制深入分析
  • git常见命令说明