Javase --- 多线程复习
admin
2024-04-04 12:22:49
0

Java 多线程

程序

静态文件 程序 启动以后以 进程方式在 操作系统驻留

进程 (可以看见)

  • 程序运行过程中 在操作系统内存中一个一个的实例。
  • 进程之间 独立存储 独立管理的 彼此是隔离的。
  • 程序 在 运行过程 中 至少有一个 进程与之对应 取决于 设计方式
  • 进程启动 默认 会启动一个 主线程(决定进程的生死 主线程死 进程死 主线程生 进程生)。

总结 :

  • 程序 执行进入内存运行,变为一个进程
  • 进程间的资源(内存、文件····)是彼此隔离的,其他进程不允许访问(读取和写入)的。

线程 (看不见)

eg :

  • 迅雷 多线程下载软件

概念 :

  • 线程 是 进程内的一个 “基本任务”,每个线程都有自己的功能, 是 CPU 分配和调度的基本单位
  • 一个进程内可以包含多个线程 , 一个线程只能隶属于一个进程
  • 进程内至少拥有一个 线程 这个线程叫做 主线程 主线程消亡 进程 结束。

CPU、进程、线程

单核 CPU

时间片(cpu 一段的执行时间 以 纳秒 为单位)
时间片 分配给 某个线程 ----> 某个线程 来执行
这种情况 叫并发执行。

多核
  • 一个线程 在同一时间 只能拥有一个 CPU 的时间片
  • 而 多个线程 在不同时间 可以 拥有不同 CPU 的时间片

这就有了 并行 执行

Java 中的 进程 与 线程

Java 最简单程序的进程 包含 main 主线程 和 垃圾收集线程(没有关注你呢)

线程创建的三种方式

Thread (不推荐使用 Java 对 继承不友好)

package nuc.zm.MoreThread.create_thread;import nuc.zm.io.ObjectIOTest.Object;/*** demo1* @description 创建线程的方式 1* @author zm* @date 2022/10/15*/
public class Demo1 {public static void main(String[] args) {TestThread testThread = new TestThread();for (int i = 0; i < 10; i++) {System.out.println("不会出现争夺资源的main" + i);}Thread thread = Thread.currentThread();thread.setName("主线程");
//        让子线程先启动 才会出现 和主线程抢夺资源的情况hhtestThread.setName("子线程");testThread.start();for (int i = 0; i < 10; i++) {System.out.println(thread.getName() + i);}}static class TestThread extends Thread {/*** 运行* 线程对象 争抢资源的任务 必须放在 run 方法中*/@Overridepublic void run() {super.run();for (int i = 0; i < 10; i++) {System.out.println(getName()  + " ==== " + i);}}}
}

Runnable (Java编程友好 单无法返回执行后的数据)

package nuc.zm.MoreThread.create_thread;/*** 以及接下来* 实现 Runnable 接口 成为线程类* @author zm* @date 2022/10/16*/
public class Demo2 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "====" + i);}}//   main 线程 启动器public static void main(String[] args) {Demo2 demo2 = new Demo2();Thread thread = new Thread(demo2);thread.setName("子线程~~");thread.start();for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "========" + i);}}
}

Callable (涉及到线程池 且线程方法具有返回值 但编程显复杂)

package nuc.zm.MoreThread.create_thread;import java.util.Random;
import java.util.concurrent.*;/*** 可调用测试** @author zm* @date 2022/11/06*/
public class CallableTest {public static void main(String[] args) throws ExecutionException, InterruptedException {ThreadTest threadTest = new ThreadTest();threadTest.start();}static class ThreadTest implements Callable {private String name;@Overridepublic Integer call() throws Exception {int speed = new Random().nextInt(10);int result = 0;for (int i = 1; i < 10; i++) {Thread.sleep(1000);result = i * speed;System.out.println("第 " + i + " 秒 " + this.name + " 已经跑到  " + result + " 米 " + " 速度 " + speed + " 米/秒 ");}return result;}public void start() throws ExecutionException, InterruptedException {
//        线程池ExecutorService executorService = Executors.newFixedThreadPool(3);ThreadTest threadTest = new ThreadTest();threadTest.name = "参赛者A";ThreadTest threadTest1 = new ThreadTest();threadTest1.name = "参赛者B";ThreadTest threadTest2 = new ThreadTest();threadTest2.name = "参赛者C";Future submit = executorService.submit(threadTest);Future submit1 = executorService.submit(threadTest1);Future submit2 = executorService.submit(threadTest2);executorService.shutdown();System.out.println(threadTest.name + "跑了" + submit.get() + "米");System.out.println(threadTest1.name + "跑了" + submit1.get() + "米");System.out.println(threadTest2.name + "跑了" + submit2.get() + "米");}}}
package nuc.zm.MoreThread.create_thread;import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;/*** demo3* 实现 callable 接口* @author zm* @date 2022/10/16*/
public class Demo3 implements Callable {/*** 调用* 抛 子类 异常* @return {@link Double}*/@Overridepublic Double call() {return (double) new Random().nextInt(10);}public static void main(String[] args) throws ExecutionException, InterruptedException {Demo3 demo3 = new Demo3();FutureTask futureTask = new FutureTask<>(demo3);Thread thread = new Thread(futureTask);thread.start();Object o = futureTask.get();System.out.println(o);}
}

线程 同步问题

现实案例 : 抛绣球案例 很多人争抢一个绣球(资源)

synchronized(同步锁)

作用 : 利用一个特定的对象设置一个锁 , 在 多线程 并发访问的时候,同时只允许一个线程 获得这个锁,并执行特定代码。
执行后 会释放锁, 继续和其他线程争抢资源。

所有线程都访问 同一个打印方法 就会出现 线程安全问题

package nuc.zm.MoreThread;/*** 同步采样* 演示 同步锁* @author zm* @date 2022/11/06*/
public class SyncSample {static class Printer {public void print() {try {Thread.sleep(500);System.out.print("你");Thread.sleep(500);System.out.print("好");Thread.sleep(500);System.out.print("世");Thread.sleep(500);System.out.print("界");} catch (InterruptedException e) {e.printStackTrace();}}}public void start() {Printer printer = new Printer();for (int i = 0; i < 10; i++) {PrintTask printTask = new PrintTask();printTask.printer = printer;Thread thread = new Thread(printTask);thread.start();}}static class PrintTask implements Runnable {private  Printer printer;@Overridepublic void run() {printer.print();}}public static void main(String[] args) {new SyncSample().start();}
}

解决 加锁

synchronized 代码块 – 任意对象
synchronized 方法 – this 当前对象
synchronized 静态方法 – 该类的字节码对象

package nuc.zm.MoreThread;import java.util.concurrent.locks.Lock;/*** 同步采样* 演示 同步锁* @author zm* @date 2022/11/06*/
public class SyncSample {static class Printer {public void print() {synchronized ("DADADADASDADAADADAD") {try {Thread.sleep(500);System.out.print("你");Thread.sleep(500);System.out.print("好");Thread.sleep(500);System.out.print("世");Thread.sleep(500);System.out.print("界");} catch (InterruptedException e) {e.printStackTrace();}}}public  synchronized  void print1() {try {Thread.sleep(500);System.out.print("你");Thread.sleep(500);System.out.print("好");Thread.sleep(500);System.out.print("世");Thread.sleep(500);System.out.print("界");} catch (InterruptedException e) {e.printStackTrace();}}public  static synchronized  void print2() {try {Thread.sleep(500);System.out.print("你");Thread.sleep(500);System.out.print("好");Thread.sleep(500);System.out.print("世");Thread.sleep(500);System.out.print("界");} catch (InterruptedException e) {e.printStackTrace();}}}public void start() {Printer printer = new Printer();for (int i = 0; i < 10; i++) {PrintTask printTask = new PrintTask();printTask.printer = printer;Thread thread = new Thread(printTask);thread.start();}}static class PrintTask implements Runnable {private  Printer printer;@Overridepublic void run() {printer.print();
//                printer.print1();
//                Printer.print2();}}public static void main(String[] args) {new SyncSample().start();}
}

线程安全

  • 在 拥有 多条线程 并行执行的程序中,线程安全的代码 会通过同步机制保证各个线程可以正常 且正确的执行,不会出现数据污染的意外情况。

线程池

JUC 并发工具包 解决 同步 和 互斥问题

  • Runnable 新建 线程 , 性能差~~~
  • 线程 被频繁创建,相互竞争,严重时可能导致系统资源死机或者内存溢出
  • 线程池 ----- 线程复用
  • ThreadPool 线程池
    • 重用 存在的线程,减少线程对象的创建,消亡的开销
    • 线程总数可控,提高资源的利用率
    • 提供额外功能,定时执行,定期执行 和 监控。
  • 支持的线程池种类
    • 工具类 Executors(juc 包下) 创建线程池
    • FixedThreadPool - 定长线程池
    • CachedThreadPool - 可缓存的线程池
    • SingleThreadPool - 单线程池
    • ScheduledThreadPool - 调度线程池

相关内容

热门资讯

【MySQL】锁 锁 文章目录锁全局锁表级锁表锁元数据锁(MDL)意向锁AUTO-INC锁...
【内网安全】 隧道搭建穿透上线... 文章目录内网穿透-Ngrok-入门-上线1、服务端配置:2、客户端连接服务端ÿ...
GCN的几种模型复现笔记 引言 本篇笔记紧接上文,主要是上一篇看写了快2w字,再去接入代码感觉有点...
数据分页展示逻辑 import java.util.Arrays;import java.util.List;impo...
Redis为什么选择单线程?R... 目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、R...
【已解决】ERROR: Cou... 正确指令: pip install pyyaml
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
Lock 接口解读 前置知识点Synchronized synchronized 是 Java 中的关键字,...
Win7 专业版安装中文包、汉... 参考资料:http://www.metsky.com/archives/350.htm...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
大模型未来趋势 大模型是人工智能领域的重要发展趋势之一,未来有着广阔的应用前景和发展空间。以下是大模型未来的趋势和展...
python实战应用讲解-【n... 目录 如何在Python中计算残余的平方和 方法1:使用其Base公式 方法2:使用statsmod...
学习u-boot 需要了解的m... 一、常用函数 1. origin 函数 origin 函数的返回值就是变量来源。使用格式如下...
常用python爬虫库介绍与简... 通用 urllib -网络库(stdlib)。 requests -网络库。 grab – 网络库&...
药品批准文号查询|药融云-中国... 药品批文是国家食品药品监督管理局(NMPA)对药品的审评和批准的证明文件...
【2023-03-22】SRS... 【2023-03-22】SRS推流搭配FFmpeg实现目标检测 说明: 外侧测试使用SRS播放器测...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
初级算法-哈希表 主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-哈希表...
进程间通信【Linux】 1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...
【Docker】P3 Dock... Docker数据卷、宿主机与挂载数据卷的概念及作用挂载宿主机配置数据卷挂载操作示例一个容器挂载多个目...