线程创建 三种方式

2023-10-28

多线程编程

一、线程、进程、多线程、程序概念

多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

简单理解下

  • 多任务:

eg:一个人边骑车边看电脑

  • 多线程:

eg:原来一条路太窄只能走一个人,现拓宽可走三个人


一个进程中可以并发多个线程,每条线程并行执行不同的任务。

进程和程序的区别?

  1. 进程是系统资源分配的单位;程序是一组有序的指令和数据的集合
  2. 进程使程序的一次执行,动态的;程序是静态的。离开进程程序也就没有存在的意义
  3. 进程具有生命周期,是暂时的;程序作为资源可以长期保存

进程和线程的区别?

  1. 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
  2. 线程是进程的一个实体,是CPU调度和分派的基本单位。它是比进程更小的能独立运行的基本单位。
  3. 一个进程可以有多个线程,进程>线程

线程主要要点:

  • 线程是系统资源分配的单位
  • 是独立的执行路径
  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程
  • 在一个进程中,若开辟了多个线程,线程的运行由调度器安排调度。调度器CPU与操作系统相关,线程运行的先后顺序不能认为干预
  • 对同一份资源操作时,会存在资源抢夺问题,需要并发控制操作
  • 主线程main()为系统的入口,用户执行整个程序
  • 线程会带来额外开销。eg:CPU调度时间,并发控制时间

二、线程创建的三种方法——重头戏

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
线程创建方式1:继承Thread类

查看JDK文档
在这里插入图片描述

Java代码实现步骤:

  1. 线程子类继承Thread类
  2. 重写run()方法,写run()方法线程执行体
  3. 在main()方法中创建子类对象实例,并调用start()方法开启线程
//集成threadCreation;

/**
 * 1.用线程类继承Thread类
 * 2.重写run()方法,写run()方法的线程执行体
 * 3.在主线程main()方法中创建线程类实例并调用start()方法
 * 4.观察每次运行的线程顺序
 */

//1.用线程类继承Thread类
public class extendThread extends Thread {
    
    //2.重写run()方法,写run()方法的线程执行体
    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("I am a runner "+ i +" !");
        }
    }

    
    //3.在主线程main()方法中创建线程类实例并调用start()方法
    public static void main(String[] args) {
        extendThread extendThread = new extendThread();
        extendThread.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("I am a mainFunction " + i +" !");
        }
    }
}

两条线程同时交替执行,同一时间只能做一件事情

每次执行的线程顺序都不一样

线程不一定立即执行,需要CPU调度

实例2:线程下载图片

先导包apache.commons.io.FileUtils【自行百度下载】

//threadCreation;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.net.URL;

public class example_InternetmapDownload extends Thread{
    private String url;
    private String name;
    public example_InternetmapDownload(String url,String name){
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        //线程执行体
        webmapDownload download = new webmapDownload();
        try {
            download.download(url,name);
            System.out.println("执行了"+ name+ "文件");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("IO出现异常");
        }
    }

    public static void main(String[] args) {
        example_InternetmapDownload t1 = new example_InternetmapDownload("https://wx2.sinaimg.cn/large/0024cZx9ly1gngdbd6ffdj60f408in4p02.jpg","01.jpg");
        example_InternetmapDownload t2 = new example_InternetmapDownload("https://wx3.sinaimg.cn/large/0024cZx9ly1gngct5epi5j60f408iwmr02.jpg","02.jpg");
        example_InternetmapDownload t3 = new example_InternetmapDownload("https://wx2.sinaimg.cn/large/0024cZx9ly1gngccx0kt2j60f408itg602.jpg","03.jpg");
        //理想状态下先下载 t1,后下载 t2,最后下载 t3
        t1.start();
        t2.start();
        t3.start();
           //执行结果:先下载 t2, 后下载 t3,最后下载 t1
//        执行了02.jpg文件
//        执行了03.jpg文件
//        执行了01.jpg文件
    }
}

//建立下载容器类
class webmapDownload{

    //创建下载方法
    public void download(String url,String name) throws Exception {
        //用url定位下载重名新名
        FileUtils.copyURLToFile(new URL(url),new File(name));
    }
}

线程创建方式2:实现Runnable接口
//threadCreation;

/**
 * 实现Runnable接口
 *  1.用线程类继承Thread类
 *  2.重写run()方法,写run()方法的线程执行体
 *  3.在主线程main()方法中创建创建Runnable接口的实现类对象,并创建线程对象代理,通过线程对象开启线程,再调用start()方法
 *  4.观察每次运行的线程顺序
 */
public class implRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("I am a runner "+ i +" !");
        }
    }

    public static void main(String[] args) {
        //创建Runnable接口的实现类对象
        implRunnable runnable = new implRunnable();
        //创建线程对象代理,通过线程对象开启线程
        new Thread(runnable).start();


        for (int i = 0; i < 1000; i++) {
            System.out.println("I am a mainFunction " + i +" !");
        }
    }
}
多线程实例

实例一:买票

//多线程买票;

public class buyTicket implements Runnable{

    private int ticketNums = 10;

    @Override
    public void run() {
        while (true){
            if (ticketNums <= 0){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前执行--->"+Thread.currentThread().getName()+"线程,拿到-->第"+ticketNums--+"票");
        }
    }

    public static void main(String[] args) {
        buyTicket ticket = new buyTicket();

        new Thread(ticket,"张三").start();
        new Thread(ticket,"李四").start();
        new Thread(ticket,"小棠").start();
    }
}

在这里插入图片描述
不同的人同时拿到相同的票数,并发问题出现【并发问题稍后】

实例二:龟兔赛跑

//多线程龟兔赛跑;

/**
 * 模拟龟兔赛跑
 */
public class race implements Runnable{
    //定义胜利者
    private static String winner;

    @Override
    public void run() {
        //模拟兔子睡觉
        if (Thread.currentThread().getName().equals("兔子")){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


        //赛道长i
        for (int i = 0; i <= 100; i++) {
            //判断比赛有没有结束
            boolean flag = isWinner(i);
            if (flag){
                break;
            }

            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }


    /**
     * 判断胜利者
     * @param i 步数
     * @return
     */
    public boolean isWinner(int i){
        //如果winner不为空,说明比赛结束
        if (winner != null){
            return true;
        }else if (i >= 100){
            //winner为空,看哪个步数走的快
            winner = Thread.currentThread().getName();
            System.out.println("winner is" + winner);
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        race race = new race();
        new Thread(race,"乌龟").start();
        new Thread(race,"兔子").start();
    }
}
线程创建方式3:实现Callable接口

查看JDK文档
在这里插入图片描述

Java代码实现步骤:

  1. 线程类实现Callable接口,有返回类型
  2. 重写call()方法,抛出异常
  3. 在main()方法中创建线程类对象,创建执行服务,提交执行,获得结果,关闭服务
  4. 运行看结果
实现Callable接口下载图片------>与继承Thread类下载图片代码比较;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

/**
 * 实现Callable接口
 * 1.线程类实现Callable接口,有返回类型
 * 2.重写call()方法,抛出异常
 * 3.在main()方法中创建线程类对象,
 *  3.1创建执行服务
 *  3.2提交执行
 *  3.3获得结果
 *  3.4关闭服务
 * 4.运行看结果
 */

public class example_CallableDownload implements Callable {
    private String url;
    private String name;
    public example_CallableDownload(String url,String name){
        this.url = url;
        this.name = name;
    }

    @Override
    public Object call() throws Exception {
        webpictureDownload webpictureDownload = new webpictureDownload();
        webpictureDownload.ptDownload(url,name);
        System.out.println("执行了" + name + "文件");
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3.在main()方法中创建线程类对象,
        example_CallableDownload d1 = new example_CallableDownload("https://wx2.sinaimg.cn/large/0024cZx9ly1gngdbd6ffdj60f408in4p02.jpg","01.jpg");
        example_CallableDownload d2 = new example_CallableDownload("https://wx3.sinaimg.cn/large/0024cZx9ly1gngct5epi5j60f408iwmr02.jpg","02.jpg");
        example_CallableDownload d3 = new example_CallableDownload("https://wx2.sinaimg.cn/large/0024cZx9ly1gngccx0kt2j60f408itg602.jpg","03.jpg");

        // 3.1创建执行服务
        ExecutorService service = Executors.newFixedThreadPool(3);
        // 3.2提交执行
        Future dl1 = service.submit(d1);
        Future dl2 = service.submit(d2);
        Future dl3 = service.submit(d3);
        // 3.3获得结果
        Object o1 = dl1.get();
        Object o2 = dl2.get();
        Object o3 = dl3.get();
        // 3.4关闭服务
        service.shutdownNow();

    }
}

//下载文件类
class webpictureDownload{
    //下载方法
    public void ptDownload(String url,String name) throws IOException {
        //代码与之前一样
        FileUtils.copyURLToFile(new URL(url),new File(name));
    }
}
3获得结果
        Object o1 = dl1.get();
        Object o2 = dl2.get();
        Object o3 = dl3.get();
        // 3.4关闭服务
        service.shutdownNow();

    }
}

//下载文件类
class webpictureDownload{
    //下载方法
    public void ptDownload(String url,String name) throws IOException {
        //代码与之前一样
        FileUtils.copyURLToFile(new URL(url),new File(name));
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程创建 三种方式 的相关文章

  • 在 Java 中将系统属性设置为 Null

    在我的单元测试中 我需要将 workingDir 系统属性设置为 Null 但我不能这样做 因为它给了我 NullPointerException System setProperty workingDir null 我该怎么做 您不能将属
  • 哪个 new 首先执行——在构造函数中还是在构造函数外?

    如果我定义一个类如下 public class myClass private x new anotherClass private y public myClass y new anotherClass 哪个变量会更早获得实例 x 或 y
  • Maven 配置文件相当于 Gradle

    我试图在我的 spring boot 项目构建中实现一个简单的场景 包括 排除依赖项以及根据环境打包 war 或 jar 例如 对于环境dev包括开发工具和包 jar 用于prod包战等 我知道它不再是基于 XML 的配置 我基本上可以在
  • Java:BufferedReader readLine() 中的 IOEXception 有何用途?

    我可以使用 try catch 循环 修复 以下异常 但我无法理解原因 为什么 in readLine 部分会不断引发IOExceptions 抛出此类异常的真正目的是什么 目标可能不仅仅是更多副作用 代码和 IOException jav
  • 在 Java 和 C 中在运行时调用名为“string”的方法

    我们如何调用名称为的方法string在运行时 谁能告诉我如何在 Java 和 C 中做到这一点 在java中可以通过反射api来完成 看一下Class getMethod String methodName Class parameterT
  • 将对象列表传递给 Freemarker 然后循环

    我已经熟悉了 FreeMarker 一个 Java 模板引擎 我已经能够通过哈希映射将对象传递给模板引擎了 这样就可以了 但是 一旦我尝试将任何类型的多个对象集传递给 FreeMarker 它就会给我一个 freemarker templa
  • 全屏独占模式下的 AWT 框架在窗口弹出对话框中最小化

    我正在开发一个在全屏独占模式下使用 awt 框架的应用程序 一切正常 直到弹出窗口可见 这会抢走焦点 我的应用程序将被最小化 这是我的框架的初始化代码 if ApplicationConfig getInstance useFullscre
  • 在 Eclipse 中导航 Java 调用堆栈

    在调试器中像GDB http sources redhat com gdb 当您在断点处停止时 您可以轻松地向上移动调用堆栈并检查相关的源和堆栈帧数据 在 Eclipse 中如何做到这一点 In the 调试视角 http www ibm
  • Selenium Webdriver 中显式等待 findElements

    登录后 页面重定向到一个页面 我想等待页面加载 我在其中按 tagName 查找元素 By inputArea By tagName input List
  • Maven:缺少工件 org.springframework:spring:jar:4.2.6

    我在 SpringToolSuite 中有一个动态 Web 项目 它被转换为 Maven 项目 我遇到问题 缺少工件 org springframework spring jar 4 2 6 我已经尝试清理 重建和运行该项目 它给 读取文件
  • Spring @Transactional 并发

    class MyService 公共无效a 同步 某个键 b Transactional 传播 传播 REQUIRES NEW 公共无效b 数据库工作吗 除非您使用代码编织 否则这是行不通的 Spring处理事务的默认方式是通过AOP代理
  • 摆动刷新周期

    我试图了解何时使用重新验证 重绘 打包 令人惊讶的是 我没有找到详细的底层文档 请随意链接 到目前为止我已经明白这都是 RepaintManager 的责任 油漆 重新油漆指的是脏 干净的东西 pack validate revalidat
  • 在 jFrame 中启用右键单击

    嘿 我正在寻找如何使用 NetBeans 在 jFrame 中启用 仅且仅 右键单击并显示弹出菜单 使用我的代码 private void formMouseClicked java awt event MouseEvent evt pop
  • Hibernate3:自引用对象

    需要一些帮助来了解如何执行此操作 我将在文件系统上运行递归 查找 并且希望将信息保留在单个数据库表中 具有自引用的层次结构 这是我想要填充的数据库表结构 目录对象表 id int NOT NULL name varchar 255 NOT
  • 获取运行时生成的类的字节

    我正在使用一个 Java 框架 该框架使用自定义类加载器在运行时生成一些 代理 类 我想为任何这样的类获取自定义 ClassLoader 从 loadClass 返回的与该类对应的原始字节数组 这可能吗 我知道 如果一个类作为资源存在 那么
  • 将 Class 对象转换为字节

    如果我有一个Class http java sun com j2se 1 5 0 docs api java lang Class html在运行时实例 我可以获得它的 byte 表示形式吗 我感兴趣的字节将在类文件格式 http java
  • 如何在其他窗口之上生成独立的 JFileChooser 对话框?

    Like 其他一些人 https stackoverflow com questions 4161207 javavm windows 7 64bit jfilechooser not showing dialog box谁问过类似的问题
  • Java可以进行进程监控吗?

    是否可以用Java编写一个在托盘中运行的应用程序 并且当启动某个应用程序时 它可以检测到它 我想对某些程序执行此操作 以了解我每周使用它们多长时间 我是 Java 新手 所以我不知道 Java 是否是最适合此操作的语言 或者它是否具有对操作
  • 在 Java Jersey 2 JAX-RS 中初始化单例

    我是泽西岛 2 22 2 的新手 请耐心等待 我正在创建一个与 LDAP 服务器交互的 REST 服务 用于存储 删除和检索用户数据 该服务通过执行加密 解密充当安全中介 在使用 REST 服务之前必须进行相当多的初始化 并且我只想执行此初
  • 如果可能,将 jFrame 输出到第二台显示器

    我在 Java 中的 Swing 上有一个 jFrame 我希望它输出到第二个监视器 如果该监视器存在 我尝试过这个 通过this http download oracle com javase 6 docs api java awt Gr

随机推荐

  • vite从零创建react-ts项目

    1 创建vite react ts文件夹 初始化项目 npm init 初始化后可以看到包管理文件package json 2 项目结构 根目录下新建index html模板文件 以往都是放在public文件夹的 但是官方推荐放在根目录 这
  • 蓝桥杯:2018年第九届蓝桥杯省赛B组第三题—乘积尾零

    如下的10行数据 每行有10个整数 请你求出它们的乘积的末尾有多少个零 5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 443
  • 软件测试面试题

    一 TCP与UDP的区别 1 连接性 TCP都面向连接的协议 使用三次握手建立连接 确保数据的可靠传输 提供可靠的数据传输服务 UDP是无连接的协议 不需要建立连接 自接发送数据包 不保证数据可靠性 2 可靠性 TCP提供更可靠的数据传输
  • 安装linux 分区 lvm,将Ubuntu安装在LVM分区上

    出自Linux Wiki 提示 此文已超过 10 年 3798 天 未更新 如发现内容过时或有误 欢迎改进 LVM是Linux提供的一种灵活的分区管理方式 如将多个磁盘看做一个分区 方便地调整LVM分区的大小 添加15个以上的分区等等 Ub
  • 后端生成PDF一些工具

    大致分为以下几种 1 利用PDF模板 读入模板 填充数据 生成带数据的PDF 先要生成自己的PDF模板 然后在模板中定义变量 等待代码填充变量值 优点 代码简单 缺点 模板要先提供 表单域的变量只能是name age这样的简单变量 而不能是
  • 使用vscode运行php

    使用vscode运行php 一 安装扩展 我们先打开vscode 然后转到安装扩展的地方 这里我们需要两个扩展 一个是php server 一个是php debug 单击安装即可 二 配置扩展 我们先新建一个php文件 单击改文件 然后 文
  • R语言中lubridate包 时间处理

    lubridate包 非常强大 能够识别各种类型的日期 字符型和时间型数据 都是格式比较特别的你数据 在处理时 比较麻烦 但是有了lubridate这个包之后 时间处理变得非常简单 这个包函数命名简单 格式比较统一 解析日期和时间 首先 l
  • npm, cnpm的安装与卸载

    很多博客都是 说的不清不楚 对于cnpm只提到了它是国内的镜像 那么对于其安装的包该如何进行删除呢 npm uninstall XXX g 安装在其它位置的同理改变 g 就可以了 即同样使用npm进行卸载
  • 基于Open3D的点云处理12-体素化

    体素化Voxelization 体素 voxel 是像素 pixel 体积 volume 和元素 element 的组合词 相当于3D空间中的像素 体素化是通过用空间均匀大小的体素网格 voxel grid 来模拟模型或者点云的几何形态的过
  • DBeaver下载安装教程

    一 简单介绍 DBeaver是一款很好用的数据库连接工具 免费的 支持100多种数据库 基本上看得见的数据库不管是关系型还是非关系型的都可用 不过可能需要下载驱动 如果驱动下载不了 连接失败 则需要配置国内的仓库 驱动下载失败的解决 htt
  • 数据仓库基本概念

    什么是数据仓库 数据仓库 英文名称为Data Warehouse 数据仓库 Data Warehouse 是一个面向主题的 Subject Oriented 集成的 Integrated 相对稳定的 Non Volatile 反映历史变化
  • Vmware15的安装(ps解决:重装Vmware出现无法安装服务Vmware Authorization Service)

    参考 Linux之Vmware的安装 作者 一只青木呀 发布时间 2020 07 09 22 13 14 网址 https blog csdn net weixin 45309916 article details 107238658 目录
  • java ssh连接_Java通过ssh远程连接服务器

    直接进入主题 一 服务器登陆公钥秘钥设置 步骤如下 1 本机生成私钥公钥文件 本机进入到 ssh目录下 c Users UserName ssh 在该目录下执行 ssh keygen t rsa 然后一路回车即可 说明 如果原先 ssh目录
  • 链表问题——长整数加法运算题解【双向链表】

    文章目录 长整数加法运算 问题描述 输入说明 输出说明 输入范例 输出范例 题解 思路 代码实现 闲谈有什么事在Linux上顺理成章 在Windows就令人费解 长整数加法运算 问题描述 假设2个任意长度的整数x y分别用链表A和B存储 现
  • 最新的hciconfig和hcitool使用说明

    hciconfig 和 hcitool 是 Linux 中的命令行工具 用于管理 Bluetooth 设备 下面是这两个工具的常用用法 hciconfig hciconfig a 显示所有可用的 Bluetooth 设备的详细信息 hcic
  • 从keystore(jks)文件中提取私钥

    JKS文件是使用keytool生成的keystore文件 存放私钥和证书 但是我们用keytool的时候 私钥并没有单独生成出来 这个不利于我们后期的一些扩展工作 所以 我们需要把私钥从keytool中提取出来 这里可以使用在线转化工具 可
  • 【2023最新版】APP测试面试题(超详细~)

    一 web测试和app测试的相同点和区别 相同点 都离不开测试的基础知识和测试原理 具体包括以下几个方面 测试用例 均使用边界值分析法 等价类划分法等 多数采用黑盒测试 来验证业务功能是否能得到正确的应用 需要检查界面布局 风格 按钮是否美
  • Hadoop之Hive

    文章目录 一 Hive简介 1 1 Hive 基本概念 1 2 Hive架构图 1 3 Hive数据模型 二 Hive安装配置 2 1 内嵌模式 2 2 配置元数据到mysql 2 3本地模式 2 4远程模式 2 5 Hive JDBC H
  • vue不是内部或外部命令!!!配置vue.cmd的path就好!!

    网上找了很多资料 基本是说对了的 主要是环境问题 path 解决办法 用Everything这个软件 或者搜索 搜索vue cmd的位置 我的地址是 我是在在node里面直接安装的vue cli 搜索到这个批处理文件后把这个文件的路径加入P
  • 线程创建 三种方式

    文章目录 多线程编程 一 线程 进程 多线程 程序概念 二 线程创建的三种方法 重头戏 线程创建方式1 继承Thread类 线程创建方式2 实现Runnable接口 多线程实例 线程创建方式3 实现Callable接口 多线程编程 一 线程