5

day31-线程基础01 - 一刀一个小西瓜

 2 years ago
source link: https://www.cnblogs.com/liyuelian/p/16653806.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

线程基础01

1.程序 进程 线程

  • 程序(program):是为完成的特定任务,用某种语言编写的一组指令的集合。简单来说,就是我们写的代码。
image-20220903181710298
    1. 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配空间。当我们使用迅雷,又启动了一个进程,操作系统将为迅雷分配新的内存空间。
    2. 进程是程序的一次执行过程,或是正在运行的一个程序。是动态过程:有它自身的产生、存在和消亡的过程。
    image-20220903182817371
    1. 线程是由进程创建的,是进程的一个实体
    2. 一个进程可以有多个线程,比如:用迅雷同时下载多个文件
  • 其他相关概念:

    1. 单线程:同一时刻,只允许执行一个线程
    2. 多线程:同一时刻,可以执行多个线程,比如:一个qq进程,可以同时打开多个聊天窗口;一个迅雷进程,可以同时下载多个文件。
    3. 并发:同一时刻,多个任务交替执行,造成一种“貌似同时”的错觉,简单地说,单核cpu实现的多任务就是并发
    image-20220903183757457
    1. 并行:同一时刻,多个任务同时执行。多核cpu可以实现并行。在电脑中也可能同时出现并发和并行的状态。
image-20220903183821311
package li.thread; public class CpuNum { public static void main(String[] args) { Runtime runtime = Runtime.getRuntime(); //获取当前的电脑的cpu数量 int cpuNums = runtime.availableProcessors(); System.out.println("当前的CPU数量="+cpuNums);//当前的CPU数量=8 }}

2.线程的基本使用

  • 创建线程的两种方式

在java中线程来使用有两种方法:

  1. 继承Thread类,重写run方法
  2. 实现Runnable接口,重写run方法
image-20220903191317462

2.1继承Thread创建线程

例子1:线程应用案例1-继承Thread类

1)请编写程序,开启一个线程,该线程每隔一秒,在控制台输出 “喵喵,我是小猫咪”

2)对上题改进:当输出80次“喵喵,我是小猫咪”时,结束该线程

3)使用JConsole监控线程执行情况,并画出程序示意图

package li.thread; //演示通过继承Thread类创建线程public class Thread01 { public static void main(String[] args) throws InterruptedException { //创建一个Cat对象,可以当做线程来使用 Cat cat = new Cat(); cat.start();//启动线程 //当main线程启动一个子线程 Thread-0后,主线程不会阻塞,会继续执行 //这时 主线程和子线程是交替执行 System.out.println("主线程继续执行="+Thread.currentThread().getName());//主线程继续执行=main for (int i = 0; i < 60; i++) { System.out.println("主线程 i="+i); //让主线程休眠 Thread.sleep(1000); } }} //1.当一个类继承了Thread类,该类就可以当做一个线程使用//2.我们会重写run方法,写上自己的业务代码//3.run Thread类实现了Runnable接口的run方法/* @Override public void run() { if (target != null) { target.run(); } } */class Cat extends Thread { @Override public void run() {//重写run方法,写上自己的业务逻辑 int times = 0; while (true) { //该线程每隔1秒,在控制台输出 “喵喵,我是小猫咪” System.out.println("喵喵,我是小猫咪" + (++times)+" 线程名称="+Thread.currentThread().getName()); //让该线程休眠一秒 try { Thread.sleep(1000);//单位为毫秒 try-catch快捷键:Ctrl+Alt+T } catch (InterruptedException e) { e.printStackTrace(); } if (times == 80) { break;//当times到80,退出while,这是线程也就退出了 } } }}

3)使用JConsole监控线程执行情况,并画出程序示意图:

如下,在控制台点击run,运行程序,在程序运行时,点击Termial

image-20220903201816455

在控制台输入JConsole,回车。

image-20220903201903908

点击本地进程,点击Thread01,点击下方连接按钮:

image-20220903202032834

在弹出窗口中点击不安全的连接按钮:

image-20220903202109982

在窗口中点击“线程”:

image-20220903202616380

可以在左下角的线程小窗口中看到main线程和Thread-0线程在同时进行

image-20220903202808116

等待一段时间,可以看到当run窗口的主线程 i = 60之后,main线程结束

image-20220903203153344

结束后:

image-20220903203145376

当线程名称=Thread-0输出到80次时,虽然可以Thread-0还在左下角,但是实际上Thread-0线程已经结束了,整个进程随之结束。

image-20220903204614562

程序示意图:

202209032116

注意:在多线程编程里面,并不一定说主线程结束了,整个进行就结束了,等所有线程都结束了,进程才会结束。

2.2为什么是start?

在2.1的例子中,主方法中定义了cat对象,该对象调用了start方法,start方法会去启动一个线程,最终会执行Cat 类的run方法。

思考一个问题:既然最终都是要调用run方法,为什么cat对象还要通过start方法对调用run呢?为什么不直接调用?

答案: 首先通过 对象.run() 方法 可以执行方法,但是不是使用的多线程的方式,就是一个普通的方法,没有真正地启动一个线程。即这时候把run方法执行完毕,才能执行主方法剩下的语句。

如下图:将cat.start();改为cat.run();之后的运行结果:

在run方法执行完之后才执行主方法剩下的语句

image-20220903213334214

那么在调用start方法时,整个过程到底是什么样子的?

点击start()方法:可以在start方法中看到一个start0()方法:

image-20220903213931518

点击start0( )方法:可以看到start0是一个本地方法,由 JVM调用,底层是c/c++实现。

image-20220903214152774

再看看run()方法的源码:可以看到run方法只是简单的调用了实现类的run,没有进行任何的多线程处理。

image-20220903215311977

换而言之,Java中真正实现多线程的效果的是start0方法,而不是run方法

202209032154

Recommend

  • 9
    • www.cnblogs.com 2 years ago
    • Cache

    day30-注解 - 一刀一个小西瓜

    Java注解 1.注解的理解 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等数据信息 和注释一样,注解不影响程序逻辑,但注解可以被编译或者运...

  • 6
    • www.cnblogs.com 2 years ago
    • Cache

    day35-IO流02 - 一刀一个小西瓜

    JavaOI流02 4.常用的类 4.1文件字节流输入流-FileInputStream InputStream抽象类是所有类字节输入流的超类 InputStream常用的...

  • 8
    • www.cnblogs.com 2 years ago
    • Cache

    day36-IO流03 - 一刀一个小西瓜

    JavaIO流03 4.常用的类02 4.4节点流和处理流

  • 9
    • www.cnblogs.com 2 years ago
    • Cache

    day38-IO流05 - 一刀一个小西瓜

    JavaIO流05 4.常用的类04 4.4节点流和处理流03 4.4.8打印流-PrintStream和PrintWriter 打印流只有输出流,没有输...

  • 6

    多用户即时通讯系统05 4.编码实现04(拓展) 拓展功能: 实现离线留言,如果某个用户不在线 ,当登陆后,可以接收离线的消息 实现离线发文件,如果某个功能没有在线,当登...

  • 6

    MySQL基础知识02 4.CRUD 数据库CRUD语句:增(create)、删(delete)、改(update)、查(Retrieve) Insert 语句 (添加数据) Update 语句(更新数据) Delete 语句(删除数据)...

  • 8

    JDBC和连接池05 11.BasicDAO 先来分析一个问题 前面我们使用了Apache-DBUtils和Druid简化了JDBC开发,但仍存在以下不足: SQL语句是固定的,不能通过参数传入,通用性不好...

  • 5

    正则表达式01 5.1正则表达式的作用 正则表达式的便利 在一篇文章中,想要提取相应的字符,比如提取文章中的所有英文单词,提取文章中的所有数字等。 ...

  • 13

    引入课程和Maven 1.Maven maven中央仓库:Maven Repository: Search/Browse/Explore (mvnrepository.com) maven仓库是国外的一...

  • 7

    搭建微服务基础环境02 3.创建使用会员微服务模块-service consumer 3.1需求分析

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK