Java多线程编程-基础篇

news2024/11/18 19:38:49

多线程相关的概念

并发

并发是指在同一时间段内,两个或多个任务在同一个处理器上交替执行,使得在宏观上看起来像是同时进行。并发是通过快速切换任务来模拟同时执行的效果,实际上在任何一个时刻点上只有一个任务在执行。

 也就是说,并发看起来像多个程序同时运行,但真相是CPU一个个按顺序快速执行的结果,给人造成程序在同一时刻都在运行的”假象“,仿佛在并行

并行

并行是指两个或多个事件在同一时刻发生,即多个指令或任务在同一时刻被多个处理器同时执行。在并行计算中,每个处理器都独立地执行任务,互不干扰。

并发就是真的多个程序在同时运行了,现在很多电脑的处理器都是多核处理器,其中多核处理器就是能够完成并行的必要条件 ,因为每个处理器在同一时刻只能处理一个事件,当我们想要达到并发的状态需要多个处理器来分别处理每个事件。

进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

 也就是说,一个程序在运行时就会产生一个进程,这个进程就是这个程序的一切数据和操作的集合,例如当我们打开浏览器时,系统中就会产生一个和浏览器相绑定的进程

线程

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

 一个程序运行后会执行各种操作,这种操作就是以线程的方式在计算机系统下执行的,例如我们打开QQ,会产生一个进程,当我们打开一个好友的聊天框又会生成这个进程的聊天框线程来完成发送消息语音通话等任务。

下面来介绍如何在java程序中实现多线程运行

Java中创建线程

1. 通过实现Runnable接口

在Java中提供了Runnable这个接口,我们想要创建新的线程可以定义新的类实现这个接口,然后实现其中的run()方法,在方法中编写我们的业务代码,这个run方法是线程的入口

查看源码我们可以看到它的代码就是这么朴实无华

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

然后我们需要知道,java中创建新的进程需要调用Thread类的start方法,但是Runnable接口中也没有start方法呀,但是我们可以创建一个Thread类型的对象,用我们定义的实现了Runnable接口的类当作构造器参数实例化一个Thread类型的对象,然后利用这个对象调用start方法,它会自动调用我们新实现的run方法

查看源码我们可以看到Thread有这样一个构造器,它的参数是Runnable类型,我们知道接口类型可以接收实现了该接口的类的引用,所以我们直接传入我们新定义的类即可

    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

下面上代码示例,大家可以自己运行试一下

public class ThRTest{

    public static void main(String []args) throws InterruptedException{

    
        Thread thread1=new Thread(new Dog());

        thread1.start();//调用start方法才会创建一个线程

        thread1.setName("狗狗线程");//给线程设置一个名字
        System.out.println(thread1.getName()+"开始执行.......");//get方法可以获取线程的名字,如果我们不自己设置,会有一个默认的名字
        
        for(int i=0;i<10;i++){
            System.out.println("主线程在执行"+i);
            Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间
        }

        
    }
    
}

class Dog implements Runnable{

    int times=0;
    @Override   //run方法中定义我们需要多线程执行的代码
    public void run() {

        while(true){

            System.out.println("狗狗线程执行中"+(++times));

            try {
                Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            if(times==20)
                break;
        }
        
    }
    
}

上面这个代码,在执行到主函数时会给主函数生成一个主线程,然后当主线程执行到我们调用start方法时会为生成一个新的线程去执行,我这个代码后又写了个循环输出字符串标记,执行这个代码我们可以得到以下结果

这里我们可以看到主函数中的输出代码和我们自己创建的线程中的输出代码是并行执行的,我刚学的时候感觉很神奇,居然还能这么玩,以上代码里面有一些Thread的方法,都很简单大家看注释应该也能看明白这里就不一一解释了。

2.通过继承Thread类

前面我们已经使用过Thread类了,其实Thread类也是实现了Runnable接口,只不过是又新增了一些创建线程相关的方法而已。

我们通过源码查看Thread类的定义

public class Thread implements Runnable 

可以看到它也是实现了接口Runnable

第一个方法中我们最后还是通过Thread类创建了线程,因为start方法只有Thread类中有,所以当我们新定义的类直接继承了Thread类的时候我们就可以直接创建我们定义的类的对象就可,因为大家知道子类会继承父类的方法,所以我们利用这个方法创建线程只需要对上面的代码略作修改

如下:


public class ThRTest{

    public static void main(String []args) throws InterruptedException{

        

        
        Thread thread1=new Dog();

        thread1.start();//调用start方法才会创建一个线程

        thread1.setName("狗狗线程");//给线程设置一个名字
        System.out.println(thread1.getName()+"开始执行.......");//get方法可以获取线程的名字,如果我们不自己设置,会有一个默认的名字
        
        for(int i=0;i<10;i++){
            System.out.println("主线程在执行"+i);
            Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间
        }

        
    }
    
}

class Dog extends Thread{

    int times=0;
    @Override   //run方法中定义我们需要多线程执行的代码
    public void run() {

        while(true){

            System.out.println("狗狗线程执行中"+(++times));

            try {
                Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            if(times==20)
                break;
        }
        
    }
    
}

结果和上面的一样这里就不展示了

为什么会有两种创建方法

很多朋友很疑惑为什么会有好几种方式创建线程,这两种方法的区别和连续??

我们可以看到两种方法,一个是通过实现接口,一个是通过继承,提到继承我们就自然而然的离不开Java的继承规则,不允许多继承,即每个类最多只能继承一个类,那如果我们新定义的Dog类继承自Animal类我们就只能利用实现Runnable接口的方式来创建线程了,算是对java继承机制的一个弥补,方便用户编程,因为现实中很多类都需要继承别的类,所以一般情况下都是利用实现接口这个方法。

实现接口类创建线程的优点

我们来看实现接口类创建线程的代码

        Dog dg=new Dog();
        Thread thread1=new Thread(dg);

        thread1.start();//调用start方法才会创建一个线程

我们只需要给Thread构造器传一个参数就可以创建线程,那么当我们需要创建大量的相同的线程时,我们就可以利用这个方式,只需要创建一个Dog类对象,然后重复创建Thread即可,如果是继承的方式,每生成一个线程我们都需要生成一个新的对象,相对来说减少了内库占用,也显得代码更加简洁实用。

总结

多线程在实际的应用程序中法非常常用,例如我们在12306买票就是一个多线程的过程,每个准备抢票的人的手机上都会生成一个抢票线程,当全国几亿人同时访问这个软件,它如何能不出错,保证系统运行正常呢,这里面涉及的并发并行和多线程知识非常之多。希望大家都要学好这一块的知识,学习在路上,加油!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计 智慧物业服务系统的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

数字IC设计\FPGA 职位经典笔试面试--整理

注&#xff1a; 资料都是基于网上一些博客分享和自己学习整理而成的 1&#xff1a;什么是同步逻辑和异步逻辑&#xff1f; 同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。 同步时序 逻辑电路的特点&#xff1a;各触发器的时钟端全部连接在一…

MFC工控项目实例之十五定时刷新PC6325A模拟量输入

承接专栏《MFC工控项目实例之十四模拟量信号名称从文件读写》 1、在BoardTest.h文件中添加代码 class CBoardTest : public CDialog { public:short m_saveData[32];unsigned short m_cardAddr;CBoardTest(CWnd* pParent NULL); // standard constructorCButtonST m_btnS…

64位系统中不支持In.vi与Out.vi的原因

在LabVIEW开发环境中&#xff0c;使用In.vi和Out.vi可以直接进行端口读写操作&#xff0c;这在32位操作系统中运行良好。然而&#xff0c;随着64位操作系统的普及&#xff0c;特别是Windows Vista及之后的系统版本&#xff0c;LabVIEW中这些VI的支持逐渐被移除。LabVIEW 2012是…

dedecms靶场(四种webshell姿势)

姿势一:通过文件管理器上传WebShell 1.登陆到后台点击【核心】【文件式管理器】【文件上传】将准备好的一句话木马上传 2.点击访问成功蚁剑连接 姿势二:修改模板文件拿WebShell 1.点击【模板】【默认模板管理】【index.htm】【修改】 在文件修改中添加一句话木马 保存 2.点击…

环境搭建2(游戏逆向)

#include<iostream> #include<windows.h> #include<tchar.h> #include<stdio.h> #pragma warning(disable:4996) //exe应用程序 VOID PrintUI(CONST CHAR* ExeName, CONST CHAR* UIName, CONST CHAR* color, SHORT X坐标, SHORT y坐标, WORD UIwide, W…

438 找到字符串中所有字母异位词

解题思路&#xff1a; \qquad 这个题目解法没什么特别的&#xff0c;遍历所有子串&#xff0c;比较与目标字符串是否满足异位词即可。唯一需要注意的是&#xff0c;提示s和p仅包含小写字母&#xff0c;且异位词不关心字符的顺序&#xff0c;可以使用长度为26的数组&#xff0c…

Unity3D类似于桌面精灵的功能实现

前言&#xff1a; 由于最近在做游戏魔改&#xff0c;很多功能在游戏里面没法实现&#xff08;没错&#xff0c;说的就是排行榜&#xff09;&#xff0c;所以准备用Unity3D开发一个类似于桌面精灵的功能部件&#xff0c;实现效果如下&#xff1a; PS&#xff1a;有需要定制的老…

MySQL聚合统计

【数据库】MySQL聚合统计 王笃笃-CSDN博客https://blog.csdn.net/wangduduniubi?typeblog显示平均工资低于2000的部门和它的平均工资 mysql> select deptno,avg(sal) deptavg from emp group by deptno; --------------------- | deptno | deptavg | --------------…

ESKF学习笔记

参考资料 https://zhuanlan.zhihu.com/p/441182819 惯性导航(三)-基于流型的ESKF及代码实现_eskf和ekf-CSDN博客 用ESKF实现IMU/GNSS组合导航&#xff08;学习记录&#xff09;_eskf imu-CSDN博客 0.ESKF与KF的区别以及总体流程 0.1卡尔曼滤波过程 卡尔曼滤波的流程按照1…

微信阅读小程序的设计与实现(lw+演示+源码+运行)

题目&#xff1a;微信阅读小程序的设计与实现 摘 要 由于APP软件在开发以及运营上面所需成本较高&#xff0c;而用户手机需要安装各种APP软件&#xff0c;因此占用用户过多的手机存储空间&#xff0c;导致用户手机运行缓慢&#xff0c;体验度比较差&#xff0c;进而导致用户会…

学习之IDEA集成GitHub

一、配置github账号 使用token登录 二、分享代码到github 2.1 当pycharm中找不到VCS时 2.2 分享代码到github 2.3 push推送代码 2.4pull拉取代码 2.5 克隆代码 三、github打开双重身份认证

Docker构建Java镜像及使用

前言 最近在项目中使用到了一些docker技术&#xff0c;因为没有专业的运维人员&#xff0c;所以在部署版本应用的时候&#xff0c;都是自己在进行打包部署。经过一段时间的操作和使用&#xff0c;在这里和大家分享一下自己的心得&#xff0c;也算是做一下总结吧。 准备工作 首…

【Unity学习心得】如何制作俯视角射击游戏

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、导入素材二、制作流程 1.制作地图2.实现人物动画和移动脚本3.制作单例模式和对象池4.制作手枪pistol和子弹bullet和子弹壳bulletShell5.制作散弹枪shotgun总…

AIDA64 Extreme(硬件检测工具)v7.20绿色不需要安装版,供大家学习研究参考

一款综合性的系统硬件检测工具,号称最权威的电脑硬件检测,监控与测试软件,这款专业的硬件检测大师也是每位高手玩家,菜鸟用户必备的硬件检测利器.AIDA64不仅提供诸如协助超频,硬件侦错,压力测试和传感器监测等多种功能,而且还可以对处理器,系统内存和磁盘驱动器性能进行全面评估…

家具行业短视频矩阵获客,轻松实现百万曝光!

当前家具行业的营销正面临一个新阶段&#xff0c;但同时也遭遇了增长的瓶颈&#xff0c;主要问题在于营销策略过于雷同&#xff0c;这导致产品难以在市场中获得足够关注&#xff0c;从而在品牌和消费者之间形成了隔阂。 同时在这样一个信息爆炸的时代&#xff0c;就算是最优秀…

pandas 生成excel多级表头

使用pandas导出excel 表格时类似这种 其中含有多级表头的情况也就是涉及到表头需要合并单元格&#xff08;横向及纵向&#xff09; 1、表头设置 columns [("xx公司路产月报表","序号","序号"),("xx公司路产月报表","单位"…

【树形dp】P2014 [CTSC1997] 选课 题解

题目描述 在大学里每个学生&#xff0c;为了达到一定的学分&#xff0c;必须从很多课程里选择一些课程来学习&#xff0c;在课程里有些课程必须在某些课程之前学习&#xff0c;如高等数学总是在其它课程之前学习。现在有 N ( 1 ≤ N ≤ 300 ) N(1\leq N \leq 300) N(1≤N≤30…

Leetcode 每日一题:Longest Increasing Path in a Matrix

写在前面&#xff1a; 今天我们继续看一道 图论和遍历 相关的题目。这道题目的背景是在一个矩阵当中找寻最长的递增数列长度。思路上非常好想&#xff0c;绝对和 DFS 相关&#xff0c;但是题目的优化要求非常高&#xff0c;对于语言和内存特性的考察特别丰富&#xff0c;如果是…

【Python报错已解决】ERROR: No matching distribution found for PIL

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一&#xff1a;安装Pillow2.2 步骤二&a…