Java多线程 - 黑马教程

文章目录

  • Java 多线程
    • 一、多线程概述
    • 二、 多线程创建方式
      • 1、继承 Thread 类创建线程
      • 2、实现 Runnable 接口
      • 3、实现 Callable 接口
    • 三、Thread 常用的方法
    • 四、线程安全
      • 什么是线程安全问题?
      • 线程安全问题出现的原因
      • 程序模拟线程安全
    • 五、线程同步
      • 线程同步方式1:同步代码块
      • 线程同步方式2:同步方法
      • 线程同步方式3:Lock 锁
    • 六、线程池
      • 什么是线程池?
      • 创建线程池
        • ThreadPoolExecutor 构造器
      • 线程池创建的注意事项(面试常问)
      • 线程池处理 Runnable 任务
      • 线程池处理 Callable 接口
    • 七、使用 Executors 工具类得到线程池
    • 八、并发和并行
      • 进程
      • 并发的含义
      • 并行的含义
    • 九、线程的生命周期
      • 什么是线程生命周期?
      • Java 线程状态
      • 线程的6种状态及互相转换
      • 线程的6种状态总结

Java 多线程

一、多线程概述

  • 线程(Thread)是一个程序内部的一条执行流程
  • 程序如果有一条执行流程,就是单线程程序
  • 多线程是指从软硬件上实现的多条执行流程的技术(多条线程由 CPU 负责调度执行)。

二、 多线程创建方式

Java 是通过 java.lang.Thread 类的对象代表多线程。主要方式有三种 :

  1. 继承 Thread 类,重写 run 方法

  2. 实现 Runnable 接口

  3. 实现 Callable 接口

1、继承 Thread 类创建线程

  1. 创建子类 MyThread 继承 Thread 线程类
  2. 重写 Thread 类的 run 方法
  3. 创建的 MyThread 线程类的对象代表一个线程
  4. 调用 start() 方法启动线程(自动执行 run 方法)

示例代码:

/**
 * 1、创建子类 MyThread 继承 Thread 线程类
 */
public class MyThread extends Thread{
   

//    2、重写 Thread 类的 run 方法
    @Override
    public void run() {
   
        super.run();

//        描述线程的执行任务
        for (int i = 1; i < 9; i++) {
   
            System.out.println("子线程 MyThread 输出:" + i);
        }
    }
}


public class ThreadTest1 {
   

    //    main 方法是由一条默认的主线程负责执行
    public static void main(String[] args) {
   
//        3、创建的 MyThread 线程类的对象代表一个线程
        Thread t = new MyThread();

//        4、启动线程(自动执行 run 方法)
        t.start(); // main线程 t线程

        for (int i = 1; i < 9; i++) {
   
            System.out.println("主线程 main 输出:" + i);
        }
    }
}

测试结果:
在这里插入图片描述

继承 Thread 类创建线程 优缺点:

  • 优点:编码简单
  • 缺点:继承了 Thread 类无法继承其他类,不利于功能扩展

多线程注意事项:

  1. 启动线程必须使用 start 方法,不是 run 方法

如果调用 run 方法,那么 Thread t = new MyThread() 就会把 t 仅仅当做一个 Java 对象而不是一个线程,此时就只有一个 main 线程,程序会先执行 run 方法然后执行下面的代码;

start 方法是向 CPU 注册,告诉 CPU Thread t = new MyThread() 是一个单独的执行流程。

  1. 不要把主线程任务放在启动子线程之前,否则永远先执行主线程再执行子线程

2、实现 Runnable 接口

  1. 定义任务类,实现 Runnable 接口
  2. 重写 run 方法
  3. 创建任务对象
  4. 把任务对象交给线程对象处理

代码示例:

/**
 * 1、定义任务类,实现 Runnable 接口
 */
public class MyRunnable implements Runnable {
   

    //    2、重写 run 方法
    @Override
    public void run() {
   

        for (int i = 1; i < 9; i++) {
   
            System.out.println("子线程输出=== " + i);
        }

    }
}


public static void main(String[] args) {
   


//        3、创建任务对象
        Runnable target = new MyRunnable();

//         4、把任务对象交给线程对象处理
//        public Thread(Runnable target)
        new Thread(target).start();

        for (int i = 1; i < 9; i++) {
   
            System.out.println("主线程 main 输出:" + i);
        }
    }

测试结果:

在这里插入图片描述

实现 Runnable 接口的匿名内部类写法

public class ThreadTest2_2 {
   
    public static void main(String[] args) {
   

//        直接创建 Runnable 接口的匿名内部类(任务对象)
        Runnable target = new Runnable() {
   
            @Override
            public void run() {
   

                for (int i = 1; i < 9; i++) {
   
                    System.out.println("子线程输出=== " + i);
                }

            }
        };

        new Thread(target).start();

//        简化形式1
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                for (int i = 1; i < 9; i++) {
   
                    System.out.println("子线程2输出=== " + i);
                }
            }
        }).start();

        //        简化形式2
        new Thread(() -> {
   

            for (int i = 1; i < 9; i++) {
   
                System.out.println("子线程3输出=== " + i);
            }

        }).start();


        for (int i = 1; i < 9; i++) {
   
            System.out.println("主线程输出:" + i);
        }

    }
}

3、实现 Callable 接口

假如线程执行完毕后需要一些数据的返回,前面两种方式重写的 run 方法均不能返回结果。

此时可以通过 Callable 接口和 FutureTask 类来实现。

通过源码可以看出来,@FunctionalInterface 表示他是一个函数式接口,同时定义了泛型与 call 方法泛型一致。如果在实现 Callable 的时候定义了泛型则重写 call 方法的返回类型返回类型固定,否则返回 Object
在这里插入图片描述
代码示例:

import java.util.concurrent.Callable;

/**
 * 1、定义任务类,实现 Callable 接口
 */
public class MyCallable implements Callable<String> {
   

    private int n;

    public MyCallable(int n) {
   
        this.n = n;
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/218336.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Opencv打开图片

cv.imread() oepncv中使用cv.imread函数读取图片&#xff0c;并打开窗口显示&#xff0c;以下是示例代码 import cv2 as cv import numpy as np from matplotlib import pyplot as pltsrc cv.imread("demo.jpg")#blue, green red cv.namedWindow("input ima…

GPIO的使用--时钟使能含义--代码封装

目录 一、时钟使能的含义 1.为什么要时钟使能&#xff1f; 2.什么是时钟使能&#xff1f; 3.GPIO的使能信号&#xff1f; 二、代码封装 1.封装前完整代码 2.封装结构 封装后代码 led.c led.h key.c key.h main.c 一、时钟使能的含义 1.为什么要时钟使能&#xff1f…

vue3 vue-cropper@next 实现图片裁切功能

Vue Cropper 实现上传图片预览&#xff0c;裁切上传效果 下载 pnpm add vue-croppernext使用 <template><inputref"inputRef"class"hidden"accept".png,.jpeg,.jpg"multipletype"file"change"handleUploadChange&quo…

C#,数值计算——计算实对称矩阵所有特征值和特征向量的雅可比(Jacobi)方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Computes all eigenvalues and eigenvectors of /// a real symmetric matrix by Jacobis method. /// </summary> public class Jacobi { private …

CUDA简介——Grid和Block内Thread索引

1. 引言 前序博客&#xff1a; CUDA简介——基本概念CUDA简介——编程模式CUDA简介——For循环并行化 Thread Index&#xff1a; 每个Thread都有其thread index。 在Kernel中&#xff0c;可通过内置的threadIdx变量来获取其thread index。threadIdx为三维的&#xff0c;有相…

音频录制软件哪个好?帮助你找到最合适的一款

音频录制软件是日常工作、学习和创作中不可或缺的一部分。选择一个适合自己需求的录音软件对于确保音频质量和提高工作效率至关重要。可是您知道音频录制软件哪个好吗&#xff1f;本文将深入探讨两种常见的音频录制软件&#xff0c;通过详细的步骤指南&#xff0c;帮助您了解它…

记一次引入低版本包导致包冲突,表现为NoClassDefFoundError的故障

简而言之&#xff0c;因为参考别的项目处理excel的代码if(org.apache.poi.hssf.usermodel.HSSFDateUtil.isCellDateFormatted(cell)) &#xff0c;为了使用这个HSSFDateUtil类我引入了依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><a…

Python3 GUI 自制音乐播放器 图片浏览 图片轮播 PyQt5(附下载地址)

目录 Part1&#xff1a; 介绍 Part2: create window Part2: create window Adv Part4: Music Play Part5&#xff1a; 图片加载&#xff1a; Part1&#xff1a; 介绍 在这篇文章中&#xff0c;我们将学习如何使用PyQt 库创建一个基本的窗口应用程序&#xff0c;并进行一些…

【C/PTA —— 14.结构体1(课内实践)】

C/PTA —— 14.结构体1&#xff08;课内实践&#xff09; 6-1 计算两个复数之积6-2 结构体数组中查找指定编号人员6-3 综合成绩6-4 结构体数组按总分排序 6-1 计算两个复数之积 struct complex multiply(struct complex x, struct complex y) {struct complex product;product.…

1-4、调试汇编程序

语雀原文链接 文章目录 1、执行过程第一步&#xff1a;源程序第二步&#xff1a;编译连接第三步&#xff1a;执行 2、DOSBox运行程序第1步 进入EDIT.EXE第2步 编写源程序第3步 编译第4步 连接第5步 执行完整过程 3、DEBUG跟踪执行过程加载程序到内存执行程序debug和源程序数字…

Selenium 自动化高级操作与解决疑难杂症,如无法连接、使用代理等

解决 Selenium 自动化中的常见疑难杂症 这里记录一些关于 Selenium的常用操作和疑难杂症。 有一些细节的知识点就不重复介绍了&#xff0c;因为之前的文章中都有&#xff01; 如果对本文中的知识点有疑问的&#xff0c;可以先阅读我以前分享的文章&#xff01; 知识点&…

【滑动窗口】LeetCode2953:统计完全子字符串

作者推荐 [二分查找]LeetCode2040:两个有序数组的第 K 小乘积 本题其它解法 【离散差分】LeetCode2953:统计完全子字符串 题目 给你一个字符串 word 和一个整数 k 。 如果 word 的一个子字符串 s 满足以下条件&#xff0c;我们称它是 完全字符串&#xff1a; s 中每个字符…

【UGUI】sprite精灵的创建与编辑

如何切图&#xff08;sprite editor&#xff09; 有时候一张图可能包含了很多张子图&#xff0c;就需要在Unity 临时处理一下&#xff0c;切开&#xff0c;比如动画序列帧图集 虽然我们可以在PS里面逐个切成一样的尺寸导出多张&#xff0c;再放回Unity&#xff0c;但是不需要这…

通讯录管理系统(基于C语言)

模块设计 本通讯录管理系统功能模块共包括9个部分&#xff1a;1.输入数据、2.显示数据、 3.插入数据、4.删除数据、5.查看数据、6.修改数据、7.保存数据、 8.返回主菜单、9.退出系统. 一&#xff0e;总体设计 通讯录的每一条信息包括&#xff1a;姓名、性别、住址、联系电话…

[leetcode ~二叉树] 模版

文章目录 1. 左叶子之和2. 翻转二叉树 E 1. 左叶子之和 :::details 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&…

java生成邮件eml文件例子

提前导入javamail.jar 仓库地址 仓库服务 导入引用类方法 import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.io.FileOutputStream; import java.util.Properties…

10、外观模式(Facade Pattern,不常用)

外观模式&#xff08;Facade Pattern&#xff09;也叫作门面模式&#xff0c;通过一个门面&#xff08;Facade&#xff09;向客户端提供一个访问系统的统一接口&#xff0c;客户端无须关心和知晓系统内部各子模块&#xff08;系统&#xff09;之间的复杂关系&#xff0c;其主要…

利用DateFormat、Date、Calendar等相关类,编程实现如下功能

&#xff08;1&#xff09;用户输入2个日期&#xff0c;第一个日期用整数形式输入&#xff0c;把输入的整数设置为日历对象1的年月日的值。第二个日期以字符串形式输入&#xff0c;形如“2022-10-25”&#xff0c;并设置为日历对象2的年月日的值。将2个日期以“xx年xx月xx日”的…

国际语音呼叫中心适用的行业有哪些?

国际语音呼叫中心的出现&#xff0c;使企业可以在全球范围内提供统一的客户支持&#xff0c;有效地解决客户服务、市场营销等国际性电话沟通问题&#xff0c;为企业提供了卓越的全球客户服务&#xff0c;确保客户在不同国家和地区之间获得一致的、高质量的支持。那么哪些行业适…

熬夜会秃头——beta冲刺Day5

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day5团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 一、团队成员会议总结 1、成员工作…