【Java|多线程与高并发】 使用Thread 类创建线程的5种方法&&如何查看程序中的线程

简介: 多线程编程主要是为了更好地解决并发编程这个问题,因为创建销毁调度一个进程开销比较大(消耗资源多和速度慢),进程之所以开销比较大,主要是在"资源的分配和回收上"而线程也被称为"轻量级进程",因此在解决并发编程这个问题上,线程的创建销毁调度的更快一些.

前言


在这里主要补充说明一些问题,方便更好地理解下面的内容:

1.关于多线程存在有什么意义以及多线程存在有什么好处?

多线程编程主要是为了更好地解决并发编程这个问题,因为创建销毁调度一个进程开销比较大(消耗资源多和速度慢),进程之所以开销比较大,主要是在"资源的分配和回收上"

而线程也被称为"轻量级进程",因此在解决并发编程这个问题上,线程的创建销毁调度的更快一些.

2.线程和进程的关系

一个进程可以有一个线程,也可以有多个线程,但是不能没有线程

在启动线程时,只有第一个线程的开销比较大,后面的开销就很小了

在不支持线程的操作系统中,进程既是资源分配的基本单位,也是调度的基本单位;在拥有线程的操作系统中,线程是调度的基本单位,而进程是资源分配的基本单位。

系统级线程的切换需要内核的支持,用户级线程的切换不需要内核的支持。同一进程中的线程共享同一物理内存空间。

3.增加线程的数量,能否提高执行速度

增加线程的数量不一定能提高速度,因为CPU核心数是有限的,如果创建线程太多,不小的开销主要在调度上浪费了

4.其它的一些知识点

线程就是独立的执行路径

main()线程也称为主线程,为系统的入口,执行整个程序,由JVM进行创建

程序运行时,即使没有手动创建线程,后台也会有多个线程,如:主线程,gc线程

在一个进程中,线程是抢占式执行,各个线程的执行顺序是不确定的

Java多线程中,最核心的类就是Thread类,而使用Thread类不需要导入任何类型的包,因为它是在java.lang包下,默认是导入的 线程主要是为了更好地解决并发编程的问题


线程创建


线程的创建有5种方法,下面为大家一一介绍这些创建线程的方法


1.继承Thread类重写run()方法


//创建线程 方法1:继承Thread 重写run方法

class MyThread extends Thread{

   @Override

   public void run() {

       while(true){

           System.out.println("run方法在执行");

       }

   }

}

public class ThreadDemo1 {

   public static void main(String[] args) {

       Thread thread = new MyThread();

       thread.start();//这里要注意

       while(true){

           System.out.println("main方法在执行");

       }

   }

}

11111.png

在创建好thread这个实例对象之后,调用的方法是start方法,而不是run方法,调用start方法是为了创建一个线程,由这个新的线程去调用thread.run方法,在run方法执行完毕后,创建的这个新的线程就自动销毁了,如果直接调用thread方法,是不会有新的线程的

程序执行流程图区别如下:

11112.png对于上述代码来说,如果只是调用thread.run()方法,那么程序只会一直打印"run方法在执行",不可能会打印"main()方法在执行"


如何查看程序中的线程?


为了更好地看到线程,Java也为我们提供了方法,我们可以使用jdk中自带的工具jconsole来查看当前进程中的所有线程

在查看线程时要运行你想要查看程序的main方法

11114.png11115.png11116.png11117.png11118.png11119.png111120.png


2.实现Runnable接口


实现Runnable接口,要重写的方法也是run()方法

//Runnable 描述一个"要执行的任务"

class MyRunnable implements Runnable{

   @Override

   public void run() {

       System.out.println("hello Thread");

   }

}

public class TreadDemo2 {

   public static void main(String[] args) {

       Runnable runnable = new MyRunnable();//描述了一个任务

       Thread thread = new Thread(runnable);//把任务交给线程来执行

       thread.start();

   }

}

这样的写法最大的好处就是解耦合,目的是为了将任务和线程之间分开


3.使用匿名内部类,继承Thread


public class ThreadDemo3 {

   public static void main(String[] args) {

       Thread thread = new Thread(){

           @Override

           public void run() {

               System.out.println("hello thread");

           }

       };

       thread.start();

   }

}

这里new Thread() 是创建了一个Thread的子类,没有名字,所以是匿名,并让thread指向这个子类对象


4.使用匿名内部类,实现Runnable


public class ThreadDemo4 {

   public static void main(String[] args) {

       Thread thread = new Thread(new Runnable() {

           @Override

           public void run() {

               System.out.println("hello thread");

           }

       });//注意()

       thread.start();

   }

}

这个写法是创建了一个子类,实现了Runnable接口,同时创建了类的实例,并传给Thread的构造方法


5.使用Lambda表达式,创建线程(重要)


这种创建线程的方法最简单,在平时使用的时候,使用Lambda表达式创建线程是最常用的,所以这种线程的创建方式要务必掌握!!!

public class ThreadDemo5 {

   public static void main(String[] args) {

      Thread thread = new Thread(()->{

          System.out.println("hello thread");

      });

      thread.start();

   }

}


Thread 的常见构造方法


Thread 的常见构造方法常见的构造方法有四种=

构造方法 说明

Thread() 创建线程对象

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

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

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

这里着重说一下第三种和第四种构造方法, 这两种构造方法可以给线程命名.给线程命名的最大好处就是当程序中创建了很多的线程,而程序中地某个线程中出现问题,可以更好地进行调试,更快地找到问题所在.


总结


掌握线程创建的方法,特别是用Lambda表达式创建线程的方法(最简单也最常用)

掌握start()和run()方法之间的区别

相关文章
|
17天前
|
人工智能 前端开发 Java
Java 面试资料中相关代码使用方法与组件封装方法解析
这是一份详尽的Java面试资料代码指南,涵盖使用方法与组件封装技巧。内容包括环境准备(JDK 8+、Maven/Gradle)、核心类示例(问题管理、学习进度跟踪)、Web应用部署(Spring Boot、前端框架)、单元测试及API封装。通过问题库管理、数据访问组件、学习进度服务和REST接口等模块化设计,帮助开发者高效组织与复用功能,同时支持扩展如用户认证、AI推荐等功能。适用于Java核心技术学习与面试备考,提升编程与设计能力。资源链接:[点此下载](https://pan.quark.cn/s/14fcf913bae6)。
49 6
Java 面试资料中相关代码使用方法与组件封装方法解析
|
18天前
|
JavaScript 前端开发 Java
Java 编程进阶实操中工具集整合组件封装方法与使用指南详解
本文详细介绍Hutool工具集和图书管理系统相关组件的封装方法及使用示例。通过通用工具类封装(如日期格式化、字符串处理、加密等)、数据库操作封装(结合Hutool DbUtil与MyBatis)、前端Vue组件封装(图书列表与借阅表单)以及后端服务层封装(业务逻辑实现与REST API设计),帮助开发者提升代码复用性与可维护性。同时,提供最佳实践建议,如单一职责原则、高内聚低耦合、参数配置化等,助力高效开发。适用于Java编程进阶学习与实际项目应用。
89 10
|
29天前
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
169 0
|
11月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
109 0
|
8月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
162 1
|
Java
Java基础系列-第一章 创建Thread的6种方式和线程常用方法
读完本章节,您将掌握如何创建线程和线程的常用方法。
254 1
Java基础系列-第一章 创建Thread的6种方式和线程常用方法
|
缓存 安全 Java
JAVA Thread Dump分析线程竞争
JAVA Thread Dump分析线程竞争
179 0
|
Java 调度
Java多线程(2)--Thread类继承和Runnable接口创建线程
Java多线程(2)--Thread类继承和Runnable接口创建线程
Java多线程(2)--Thread类继承和Runnable接口创建线程
|
安全 Java Linux
【Java原理探索】站在Linux操作系统角度去看Thread(线程) | Java开发实战
【Java原理探索】站在Linux操作系统角度去看Thread(线程) | Java开发实战
253 0
|
Java 程序员 API
java多线程编程_Thread类_线程状态的理解
java多线程编程_Thread类_线程状态的理解
103 0
java多线程编程_Thread类_线程状态的理解