Java,多线程,线程的两种创建方式

首先是多线程的一些相关概念:

相关概念:

程序(program):为完成特定任务,用某种语言编写的一组指令的集合。即指一段静态(指不在执行中)的代码。

进程(process):程序的一次执行过程,或是正在内存中运行的应用程序。

        ·每个进程都有一个独立的内存空间,系统运行一个程序即是一个进程从创建、运行到消亡的过程。(声明周期)

        ·程序是静态的,进程是动态的。

        ·进程作为操作系统调度和分配资源的最小单位(亦是系统运行程序的基本单位),系统在运行时会为每个进程分配不同的内存区域。

线程(thread):进程可以进一步细化为线程,时程序内部的一条执行路径。一个进程中至少有一个线程。

        ·一个进程同一时间若并行执行多个线程,就是多线程的。

        ·线程是作为CPU调度和执行的最小单位。

        ·一个进程中的多个线程共享相同的内存单元,它们从一个堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源就可能会带来安全的隐患。

        注:不同的进程之间是不共享内存的。进程之间的数据交换和通信的成本很高。

线程调度:

        ·分时调度:所有线程轮流使用CPU的使用权,并且平均分配每个线程占用CPU的时间。

        ·抢占式调度:让优先级高的线程以较大的概率优先使用CPU。如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

多线程程序的优点:

        提高应用程序的响应。对图形化界面更有意义,可增强用户体验。

        提高计算机系统CPU的利用率。

        改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。

并行与并发:

并行(parallel):指两个或多个事件在同一时刻发生。指在同一时刻,有多条指令在多个CPU上同时执行。

并发(concurrency):指两个或多个事件在同一个时间段内发生。即在同一段时间内,有多条指令在单个CPU上快速轮换、交替执行,使得在宏观上具有多个进程同时执行的效果。

Java,多线程,线程创建方式一:继承Thread类

 Java语言的JVM允许程序运行多个线程,使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。

Thread类的特性:

    ①每个线程都是通过某个特定的Thread对象的run( )方法来完成操作的,因此把run( )方法称为线程执行体。

    ②通过该Thread对象的start( )方法来启动这个线程,而非直接调用run( )方法。

    ③想要实现多线程,必须在主线程中创建新的线程对象。

通过继承Thread类来创建并启动多线程的步骤如下:

①定义Thread的子类,并重写该类的run( )方法,该run( )方法的方法体就代表了线程需要完成的任务。

②创建Thread类的子类的实例,即创建了线程对象。

③调用线程对象的start( )方法来启动该线程。

start( )的作用:①启动线程②调用当前线程的run( )方法。

以下代码的实现为例:

两个线程分别遍历10000以内的偶数:

public class EvenNumberTest

{

    public static void main(String[] args)

    {

        //③创建当前Thread类的子类的对象
        PrintNumber t1 = new PrintNumber();
        //通过对象调用start()方法
        t1.start();

        //main方法所在的线程的执行的操作
        for (int i = 1; i <= 10000; i++)
        {
            if(i % 2 == 0)
            {
                System.out.println(i + "及你太美");
            }
        }
    }
}

//①创建一个继承于Thread的子类
class PrintNumber extends Thread
{
    //②重写Thread类的run方法,并将此线程的要执行的操作,声明在此方法体中

    @Override
    public void run()
    {
        for (int i = 1; i <= 10000; i++)
        {
            if(i % 2 == 0)
            {
                System.out.println(i);
            }
        }
    }
}

可以发现到两个进程的交替的运行的状况:

注意点一:

如果不调用start( )方法,直接调用run( )方法,便不会开启新的线程。

注意点二:

不能让已经start的线程,再次执行start( ),否则会报异常。正确做法应该是再创建一个新的对象,用新的对象调用start( )方法。

可以利用匿名内部类的方法写出   遍历100以内的奇数和偶数的俩个线程(创建两个匿名内部类(Thread类的子类的匿名)):

class EvenNumber extends Thread
{
    @Override
    public void run()
    {
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 0)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}

class OddNumber extends Thread
{
    @Override
    public void run()
    {
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 1)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}

public class PrintNumberTest

{
    public static void main(String[] args
    {
//        EvenNumber e = new EvenNumber();
//        OddNumber o = new OddNumber();
//        e.start();
//        o.start();

        //方式二
        new Thread(){
            public void run()
            {
                for (int i = 1; i <= 100; i++)
                {
                    if(i % 2 == 0)
                    {
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                    }
                }
            }
        }.start();

        new Thread(){
            public void run()
            {
                for (int i = 1; i <= 100; i++)
                {
                    if(i % 2 == 1)
                    {
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                    }
                }
            }
        }.start();
    }
}

Java,多线程,线程创建方式二:实现Runnable接口

步骤:

①创建一个实现Runnable接口的类

②实现接口中的run( )方法,将此线程要执行的操作,声明在此方法体中。

③创建当前实现类的对象

④将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例。

⑤Thread类的实例调用start( )方法。

基本步骤的样例如下:

//①创建一个实现Runnable接口的类
class EvenNumberPrint implements Runnable
{
//②创建接口中的run()方法,将此线程要执行的操作,声明在此方法体中
    @Override
    public void run()
    {
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 0)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}
public class EvenNumberTest
{
    public static void main(String[] args)
    {
        EvenNumberPrint e = new EvenNumberPrint();//创建Runnable类的实现类的对象。
        Thread thread = new Thread(e);//创建thread类的对象,调用参数为Runnable的实现类的构造器,将实现类的对象代入构造器中去。
        thread.start();//直接调用Thread的对象的start方法。
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 1)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }


        Thread tt = new Thread(e);//要再创建一条新的线程,执行同样的操作,不用再创建实现类的对象,只要再创建Thread的对象就可以,参数用的依然是同一个实现类的对象。
        tt.start();
    }
}
同样 可以利用匿名内部类的方法写出   遍历100以内的奇数和偶数的俩个线程:
public class PrintNumberTest
{
    public static void main(String[] args)
    {
//        EvenNumber ee = new EvenNumber();
//        OddNumber oo = new OddNumber();
//        Thread t1 = new Thread(ee);
//        Thread t2 = new Thread(oo);
//        t1.start();
//        t2.start();


        //匿名的Thread的子类,参数为匿名的Runnable的实现类的匿名对象。
        new Thread(new Runnable(){
            public void run()
            {
                for (int i = 1; i <= 100; i++)
                {
                    if(i % 2 == 0)
                    {
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                    }
                }
            }
        }).start();
        new Thread(new Runnable(){
            public void run()
            {
                for (int i = 1; i <= 100; i++)
                {
                    if(i % 2 == 1)
                    {
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                    }
                }
            }
        }).start();
    }
}


class EvenNumber implements Runnable
{
    public void run()
    {
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 0)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}


class OddNumber implements Runnable
{


    @Override
    public void run()
    {
        for (int i = 1; i <= 100; i++)
        {
            if(i % 2 == 1)
            {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}
线程创建的俩种方式的对比:
共同点:
①启动线程,使用的都是Thread类中定义的start( )方法。
②创建的线程对象,都是Thread类或Thread的子类的实例。
不同点:
方式一是类的继承,方式二是接口的实现。
建议使用Runnable接口的方式
实现Runnable接口的方式的好处:
①一个类可以实现多个接口,避免了类的单继承的局限性。
②创建多个线程对象的构造器的参数(Runnable的实现类)可以使用同一个实现类的对象,更适合处理有共享数据的问题。
③实现了代码和数据的分离。
联系:
Thread类实现了Runnable接口。体现了代理模式。

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

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

相关文章

Qt QTableWidget表格的宽度

默认值 QTableWIdget的表格宽度默认是一个给定值&#xff0c;可以手动调整每列的宽度&#xff0c;也不填满父窗口 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {this->resize(800,600);QStringList contents{"11","111111111111",&…

聊聊模板引擎<Template engine>

模板引擎是什么 模板引擎是一种用于生成动态内容的工具&#xff0c;通常用于Web开发中。它能够将静态的模板文件和动态数据结合起来&#xff0c;生成最终的HTML、XML或其他文档类型。模板引擎通过向模板文件中插入变量、条件语句、循环结构等控制语句&#xff0c;从而实现根据…

操作系统:输入输出管理(一)系统概述与设备独立性软件

一战成硕 5.1 I/O系统概述5.1.1 I/O设备5.1.2 I/O控制方式5.1.3 I/O软件层次结构5.1.4 应用程序的I/O接口 5.2 设备独立性软件5.2.1 与设备无关的软件5.2.2 高速缓存与缓冲区5.2.3 设备分配与回收5.2.4 spooling技术&#xff08;假脱机技术&#xff09; 5.1 I/O系统概述 5.1.1…

一分钟秒懂人工智能对齐

文章目录 1.什么是人工智能对齐2.为什么要研究人工智能对齐3.人工智能对齐的常见方法 1.什么是人工智能对齐 人工智能对齐&#xff08;AI Alignment&#xff09;指让人工智能的行为符合人的意图和价值观。 人工智能系统可能会出现“不对齐”&#xff08;misalign&#xff09;…

【EI会议征稿】JPCS独立出版-第五届新材料与清洁能源国际学术会议(ICAMCE 2024)

JPCS独立出版-第五届新材料与清洁能源国际学术会议&#xff08;ICAMCE 2024&#xff09; 2024 5th International Conference on Advanced Material and Clean Energy 第五届新材料与清洁能源国际学术会议&#xff08;ICAMCE 2024&#xff09;将于2024年2月23-25日在中国▪长沙…

电机应用-无刷直流电机

无刷直流电机 无刷直流电机&#xff08;Brushless Dirent Current Motor&#xff0c;简称BLDCM&#xff09;由电动机主体和驱动器组成&#xff0c;无电刷和无换向器&#xff0c;是除了有刷电机外用得最多的一种电机。 无刷直流电机不使用机械的电刷装置&#xff0c;采用方波自控…

带你一分钟看懂 “kubernetes”

目录 什么是 Kubernetes Kubernetes 概述 为什么需要 Kubernetes&#xff0c;它能做什么&#xff1f; 什么是 Kubernetes 从官方网站上可以看到&#xff0c;它是一个工业级的容器编排平台。Kubernetes 这个单词是希腊语&#xff0c;它的中文翻译是“舵手”或者“飞行员”。在…

NFT Insider112:Gucci Cosmos LAND亮相 The Sandbox,和YGG一起探索Web3增长新方式

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto&#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周…

0基础制作产品图册的干货,一个网站即可

很多朋友想要制作产品图册&#xff0c;但是不知道如何入手&#xff0c;其实制作产品图册并不难&#xff0c;一个网站就可以搞定。下面就为大家分享一些干货&#xff0c;帮助大家快速入门。 首先&#xff0c;我们需要选择一个合适的网站。比如FLBOOK在线制作电子杂志平台。这个网…

【chat】3: ubutnu 安装mysql-8

如何在 Ubuntu 20.04 上安装 MySQLC搭建集群聊天室&#xff08;七&#xff09;&#xff1a;MySQL数据库配置 及项目工程目录配置 大神是centos的. apt 安装 rootk8s-master-2K4G:~# sudo apt install mysql-server Reading package lists... Done Building dependency tree Re…

SQL触发器

触发器是与表有关的数据库对象。 在insert/update/delete之前(BEFORE)或之后(AFTER)&#xff0c;触发并执行触发 器中定义的SQL语句集合。 触发器的这种特性可以协助应用在数据库端确保数据的完整性, 日志记录 , 数据校验等操作 。 使用别名OLD和NEW来引用触发器中发生变化的…

Google play提高上包率——如何防止封号、拒审、下架?

Google Play是全球最大的移动应用商店之一&#xff0c;它是运行Android操作系统的设备的官方应用商店。它提供各种数字内容&#xff0c;包括应用程序&#xff08;应用&#xff09;、游戏、音乐、书籍等&#xff0c;包括免费和付费选项。这也为许多游戏/APP出海的企业或开发者提…

国内首批!华为云云原生中间件DCSDMS获软件可信“卓越级”认证

11月6日&#xff0c;在软件供应链可信研讨大会上&#xff0c;工业和信息化部电子第五研究所&#xff08;以下简称“电子五所”&#xff09;发布了首批软件产品可信评估结果&#xff0c;并为通过评估的企业颁发证书。 华为云作为中国领先的综合云计算服务商受邀参加本次大会&…

【星海随笔】git的使用

1.在终端&#xff0c;检查git是否安装 git --version 2.没有安装的话去&#xff0c;官网&#xff0c;下载git 3.一直点下一步即可 4.安装后在终端检查git是否安装好 5.设置用户名和邮件地址(最好和GitHub的用户名/邮箱保持一致) git config --global user.name “自己的用户名”…

建表时如何合理选择字段类型

前言 我们在建表的时候关于字段类型的选择会有这么几类人&#xff1a; 严谨型 严格调研每个字段可能的大小&#xff0c;然后根据不同字段类型的限制&#xff0c;进行选择&#xff0c;这一类人在创建关系型数据表的时候是没有问题的。图自己省事型 把所有字段都设置为String&a…

100 寻找重复数

寻找重复数 题解1 二分法题解2 快慢指针(同环形链表2(ab)(ab)kL) 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返…

使用Pytorch的一些小细节(一)

文章目录 前言数据结构-张量max函数索引函数赋值函数拼接函数 前言 由于不经常动手写代码&#xff0c;所以对于python语言中的常见数据结构的用法也不是很熟悉&#xff0c;对于pytorch中的数据结构就更加不熟悉了。之前的代码基础是基于C语言的&#xff0c;属性都是自己定义&a…

动态规划-构建乘积数组

** 描述 给定一个数组 A[0,1,…,n-1] ,请构建一个数组 B[0,1,…,n-1] ,其中 B 的元素 B[i]A[0]A[1]…*A[i-1]A[i1]…*A[n-1]&#xff08;除 A[i] 以外的全部元素的的乘积&#xff09;。程序中不能使用除法。&#xff08;注意&#xff1a;规定 B[0] A[1] * A[2] * … * A[n-1…

量子计算和量子通信技术:引领潜力无限的未来

近年来&#xff0c;随着量子计算和量子通信技术的迅速发展&#xff0c;它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用&#xff0c;以及它们预示的未来&#xff0c;同时提出业内人士需要注意的事项。 介绍&#xff1a;量子…

【Spring之底层核心架构概念解析】

文章目录 一、BeanDefinition二、BeanDefinitionReader2.1、AnnotatedBeanDefinitionReader2.2、XmlBeanDefinitionReader 五、ClassPathBeanDefinitionScanner六、BeanFactory七、ApplicationContext7.1、AnnotationConfigApplicationContext7.2、ClassPathXmlApplicationCont…