首页 > 编程语言 >【高级编程】认识Java多线程 代码举例三种创建线程的方式

【高级编程】认识Java多线程 代码举例三种创建线程的方式

时间:2024-09-11 11:52:17浏览次数:13  
标签:Java Thread Callable start 线程 new 多线程 public

文章目录

进程:应用程序的执行实例,有独立的内存空间和系统资源

线程:CPU调度和分派的基本单位,进程中执行运算的最小单位,可完成一个独立的顺序控制流程

多线程:如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”。多个线程交替占用CPU资源,而非真正的并行执行

一个程序有一个进程。一个进程包含多个线程(必有一个主线程)

多线程好处:

  • 充分利用CPU的资源

  • 简化编程模型

  • 带来良好的用户体验


主线程

Java 提供了 java.lang.Thread 类支持多线程编程

主线程

  • main() 方法即为主线程入口

  • 产生其他子线程的线程

  • 必须最后完成执行,因为它执行各种关闭动作

// 查看线程
public static void main(String args[]) {
		Thread thread = Thread.currentThread(); 
		System.out.println("当前线程是: " + thread.getName()); 
		thread.setName("MyJavaThread"); 
		System.out.println("当前线程名是: " + thread.getName()); 
}
当前线程是: main
当前线程名是: MyJavaThread

Java 中创建线程的 3 种方式

​ 继承 java.lang.Thread

​ 实现 java.lang.Runnable 接口

​ 实现 java.util.concurrent.Callable 接口

使用线程的步骤

定义线程;创建线程对象;启动线程;终止线程

创建线程

方式1:Thread

1、继承 Thread 类创建线程

2、重写 run() 方法,编写线程执行体

3、创建线程对象,调用 start() 方法启动线程

public class MyThread extends Thread{
    //重写run()方法
    public void run(){
        for(int i = 1; i <= 10; i++){
            System.out.println(Thread.currentThread().getName()+" : "+i);
        }
    }
}
public static void main(String[] args) {
    MyThread thread1 = new MyThread();
    thread1.setName("线程1"); // 设置线程名
    thread1.start();         // 启动线程
    
    MyThread thread2 = new MyThread();
    thread2.setName("线程2");
    thread2.start();
}

多个线程交替执行,不是真正的“并行”,线程每次执行时长由分配的CPU时间片长度决定。

线程1 : 1
线程1 : 2
线程1 : 3
线程2 : 1
线程1 : 4
线程1 : 5
线程1 : 6
线程2 : 2
线程1 : 7
线程2 : 3
线程1 : 8
线程2 : 4
线程2 : 5
线程1 : 9
线程2 : 6
线程1 : 10
线程2 : 7
线程2 : 8
线程2 : 9
线程2 : 10

调用 run():只有主线程一条执行路径

调用 start():多条执行路径,主线程和子线程并行交替执行

方式2:Runnable

1、定义 MyRunnable 类实现 Runnable 接口

2、重写 run() 方法,编写线程执行体

3、创建 Thread 对象 new Thread(Runnable),调用 start() 方法启动线程

public class MyRunnable implements Runnable{
    public void run(){
        for(int i = 1; i <= 10; i++){
            System.out.println(Thread.currentThread().getName()+" : "+i);
        }
    }
}
public static void main(String[] args) {
    MyRunnable myRunnable = new MyRunnable();
    Thread thread1 = new Thread(myRunnable);	
    thread1.start(); //启动线程
    
    Thread thread2 = new Thread(myRunnable);	
    thread2.start();
}

方式3:Callable

1、定义 MyCallable 类实现 Callable<> 接口

2、重写 call() 方法,编写线程执行体(注意:有返回值)

3、使用 FutureTask 包装 Callable 对象,调用 start() 方法启动线程

4、使用 futureTask.get() 获取线程的返回值

import java.util.concurrent.Callable;

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        // 执行任务
        for (int i = 1; i <= 10; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            // 模拟一些工作
            Thread.sleep(100); // 添加延迟以便观察线程执行
        }
        return "这是MyCallable";
    }
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
// 测试
public class Test{
    public static void main(String[] args) {
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask1 = new FutureTask<>(myCallable);
        FutureTask<String> futureTask2 = new FutureTask<>(myCallable);
        Thread thread1 = new Thread(futureTask1);
        thread1.start();
        Thread thread2 = new Thread(futureTask2);
        thread2.start();
        // 接收返回值
        try {
            System.out.println("futureTask1返回值: " + futureTask1.get());
            System.out.println("futureTask2返回值: " + futureTask2.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

比较 Thread Runnable Callable 三种创建线程的方式

  • 继承 Thread 类:适用于简单的线程任务,不需要重用线程逻辑。单继承
  • 实现 Runnable 接口:适用于线程任务逻辑需要重用,且可以将任务与线程分离。避免单继承局限性
  • 实现 Callable 接口:适用于需要线程计算结果,并能处理异常的场景。

标签:Java,Thread,Callable,start,线程,new,多线程,public
From: https://blog.csdn.net/m0_66584716/article/details/142136046

相关文章

  • java常规web面试题考点
    在java的理论知识中,有一个模块作为最基础的组成,但在学习的难度上较大所以往这方面发展的人不多。其实这就是web模块,开发一些软件都离不开web方面的理论支撑。web面试题主要考察一些基础开发的工具的用法和实际代码运用的试题,下面我们来就具体的题目进行作答。1.网络编程首先要......
  • 【JAVA】第五天
    【JAVA】第五天一、Math类二、System类三、Runtime类四、BigDecimal类五、JDK8之前传统的日期、时间(不推荐)1.Date类2.SimpleDateFormat类3.Calendar类六、JDK8之后新增的日期、时间1.LocalDateTime类2.ZoneId类3.ZonedDateTime类4.Instant类5.DateTimeFormatter类6.Peri......
  • [JavaScript] 事件委托以及 Vue 列表循环事件绑定的性能优化
    前言事件委托(EventDelegation)是一种通过将事件监听器绑定到父元素,而不是直接绑定到每个子元素上的技术。这样可以减少事件监听器的数量,提升性能,并使得对动态添加或移除的元素更容易进行事件处理。事件冒泡和事件捕获事件冒泡:从里往外<divid="parent"style="padding:50px;......
  • Java八股复习指南-集合
    Java集合MapHashMap实现原理/底层Java1.8之前:数组加链表Java1.8之后:当一个链表的长度超过8,且数组大小超过64时,会将链表转换成红黑树存储,查找效率更高,时间复杂度O(logn)。如果长度超过8,但是数组容量不足64,则会选择扩容数组。定位算法计算key的哈希值,并进行与运算intindex......
  • Java八股复习指南-基础
    Java基础接口和抽象类有什么区别?在设计动机上有所有不同接口是自上而下的设计。我们提前设计了一些行为,于是基于这些行为定义一个接口,一些类需要有这些行为,就会实现这个接口。而抽象类是自下而上的设计。当我们写了很多类时,发现他们有很多的共性,于是把这些逻辑抽象出来,减少代......
  • 计算机毕业设计选题推荐-作品分享交流平台(摄影、绘画、书法)-Java/Python项目实战(亮点:
    ✨作者主页:IT毕设梦工厂✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......
  • 计算机毕业设计选题推荐-企业人事管理系统-Java/Python项目实战
    ✨作者主页:IT毕设梦工厂✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......
  • 动态规划算法之矩阵链乘法详细解读(附带Java代码解读)
    矩阵链乘法(MatrixChainMultiplication)问题是动态规划中的经典问题之一。该问题的核心目标是在给定的矩阵链中,找到一种最优的乘法顺序,使得计算矩阵乘积的标量乘法次数最小。1.问题描述给定一个矩阵链(A1,A2,...,An),要求计算从第一个矩阵A1​到最后一个矩阵An的乘积A1......
  • 进程 vs 线程
    进程vs线程好的,让我们通过对比的方式来详细说明进程和线程之间的区别,以便更好地理解它们各自的特性和适用场景。进程vs.线程1.资源拥有与共享进程:每个进程都有自己的独立地址空间和资源(如文件句柄、内存映射等)。进程之间的资源是隔离的,这意味着一个进程中的修改不会......
  • RuoYi 开源框架,集成了后端管理,后端java版 App 移动解决方案
    文章目录前言一、后端:二、后台管理三、App移动总结前言后端:后台管理:使用的前端技术Vue、Element后端SpringBoot&Security完全分离的权限管理系统。App移动解决方案:采用uniapp框架提示:以下是本篇文章正文内容,下面案例可供参考一、后端:基于SpringBoot,Sprin......