Java:多线程基础(一)-创建线程的两种方式

news2024/11/26 2:40:14

目录

线程与进程

Thread类        

创建线程的两种方式

方式1:继承Thread类 

方式2:实现Runnable接口

* 方式2延伸:实现Callable接口

Callable接口

Futuretask类

返回线程计算结果:get()

Callable:创建子线程

补充点

(1)采用实现Runnable、Callable接口的方式创建多线程的优缺点

(2)采用继承Thread类的方式创建多线程的优缺点



线程与进程

        线程,不同于我们所熟知的进程,是更为细粒度的程序执行单元。换言之,一个进程可以表示一个应用程序,但是一个线程只能用于表示这个应用程序的一条执行路径。例如:QQ进程,可能包含了n个线程,用于管理界面交互、收发聊天消息、接口系统信息等等。

        如下图所示,我们可以看到,当前计算机中运行着的线程数远远大于进程数。

Thread类        

         在Java编程语言将线程抽象为Thread类,用Thread类来描述线程的概念,并拟定了优先级(priority)、守护线程(daemon Thread)、等相关的属性。

         jdk8源码文档注释内容如下,

        A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
    线程是一个进程/程序(Program)的一条执行路径,JVM虚拟机允许一个应用同时执行多个线程。

        Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon.
    When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the
creating thread, and is a daemon thread if and only if the creating thread is a daemon.
    线程拥有一个优先级别(priority),优先级高的优先于优先级低的线程执行。一个线程可能是守护线程。
    当线程A在执行过程中创建了一个新的线程a,则:线程a默认拥有与线程A同样的优先级。当且仅当线程A是一个守护线程时,线程a才会成为守护线程。

        When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class).
     Java虚拟机一经启动,就会有一个非守护线程——对应于main方法开始执行。

       The Java Virtual Machine continues to execute threads until either of the following occurs:
    (1)The <code>exit</code> method of class Runtime has been called and the security manager has permitted the exit operation to take place.
    (2)All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
    JVM虚拟机结束执行多线程状态的两种情况:
    (1)Runtime类的exit()方法被调用,并且,security manager管理器也允许退出操作被执行。
    (2)所有的非守护线程都已死亡,可以是run()方法正常执行结束,也可以是run()方法执行过程中抛出了异常,都会导致该线程结束执行。 

创建线程的两种方式

        jdk1.8源码的文档注释中指出,java有两种创建线程的方式。

There are two ways to create a new thread of execution.

方式1:继承Thread类 

One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and started.

方式1:定义一个Thread类的子类SubThread,然后重写Thread类的run()方法,然后创建一个SubThread子类的实例,将其启动即可;

        如下为参考jdk1.8中给出的示例程序编写的线程测试demo:创建一个子线程,用于打印子线程所持有的成员属性minPrime的值。

class PrimeThread extends Thread {
    long minPrime;
    PrimeThread(long minPrime) {
        this.minPrime = minPrime;
    }
    @Override
    public void run() {
        // compute primes larger than minPrime
        System.out.println(this.minPrime);
    }
}

public class Thread_Class {
    //properties

    //methods
    public static void main(String[] args) {
        //创建子线程
        Thread thread = new PrimeThread(100);
        //启动子线程
        thread.start();
    }
}

 方式2:实现Runnable接口

  The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started. 

第二种方式是:创建一个Runnable接口的子类SunRunnable,然后实现run()方法。接着创建SunRunnable子类对象,将其作为参数传递给Thread类,将其启动即可。

        以下为参考jdk1.8源码示例程序完善的创建子线程的demo,同样:用于打印一个数字。

//方式2-实现Runnable接口
class PrimeRun implements Runnable {
    long minPrime;

    PrimeRun(long minPrime) {
        this.minPrime = minPrime;
    }

    public void run() {
        // compute primes larger than minPrime
        System.out.println(minPrime);
    }
}

public class Thread_Class {
    //properties

    //methods
    public static void main(String[] args) {
        //创建子线程
        Runnable runnable = new PrimeRun(10);
        //启动子线程
        new Thread(runnable).start();
    }
}

 * 方式2延伸:实现Callable接口

Callable接口

        由于Runnable接口的run()方法只能用来执行子线程任务,但是没有返回值。因此,jdk又引入了Callable接口,用于创建一个带返回值的线程。

        jdk8源码文档注释描述如下,


        A task that returns a result and may throw an exception.
Implementors define a single method with no arguments called
{@code call}.
       Callable接口用于创建一个返回结果的线程(可能抛出异常)。该接口的实现者需要重写一个无参方法call().
    <p>The {@code Callable} interface is similar to {@link java.lang.Runnable}, in that both are designed for classes whose instances are potentially executed by another thread.  A {@code Runnable}, however, does not return a result and cannotthrow a checked exception.
    Runnable接口的run()方法既没有返回值,也不会抛出异常,而Callable接口的call()方法就可以。当无法计算返回值的时候,Callable接口的call()方法就抛出异常;如果可计算出结果,就将其返回,并正常结束子线程的执行。

        Callable作为一个函数式接口,其源码如下,

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Futuretask类

         使用Callable接口创建子线程,需要借助Futuretask类,该类作为Runnable接口的子类,提供了有参构造可以接收Callable接口的实例。因此,创建子线程时,可将FutureTask实例作为参数传递给Thread类的构造器完成

 返回线程计算结果:get()

        FutureTask子类提供了get()方法,可等待子线程计算结果,并将其返回。通过这个方法,可以获取子线程的计算结果值。

 Callable:创建子线程

        使用Callable接口创建子线程的示例代码如下,具体是:通过Callable接口、FutureTask类、Thread类创建了一个子线程,获取用于返回该子线程持有的成员属性的值,随后通过get()方法,获取子线程的计算结果。

class PrimeCallable implements Callable{
    long timelong ;

    public PrimeCallable(long timelong){
        this.timelong = timelong;
    }

    @Override
    public Object call() throws Exception {
        return this.timelong;
    }
}

public class Callable_interface {
    //properties

    //methods
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建Callable接口子类
        Callable callable = new PrimeCallable(1000);
        //创建Runnable接口实例
        FutureTask runnable = new FutureTask(callable);
        //创建子线程
        Thread thread = new Thread(runnable);
        //启动子线程
        thread.start();

        //获取接收线程计算的结果值
        Object o = runnable.get();
        System.out.println(o);
    }
}

补充点

(1)采用实现Runnable、Callable接口的方式创建多线程的优缺点

  • 线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。

  • 在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

  • 劣势是,编程稍稍复杂,如果需要访问当前线程,则必须使用Thread.currentThread()方法

(2)采用继承Thread类的方式创建多线程的优缺点

  • 劣势是,因为线程类已经继承了Thread类,所以不能再继承其他父类。

  • 优势是,编写简单,如果需要访问当前线程,则无须使用Thread.currentThread()方法,直接使用this即可获得当前线程。

PS:鉴于上面分析,因此一般推荐采用实现Runnable接口、Callable接口的方式来创建多线程。

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

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

相关文章

Redis实战之共享session + jwt 实现登录拦截、刷新token

共享session问题 每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat&#xff0c;并且把自己的信息存放到第一台服务器的session中&#xff0c;但是第二次这个用户访问到了第二台tomcat&#xff0c;那么在第二台服务器上&#xff0c;肯定没有第一台服务器…

百度边止血边扩张

在经过一系列的“内部调整”之后&#xff0c;百度交出了一份超预期的财报。北京时间11月22日&#xff0c;百度发布了截至2022年9月30日的第三季度财务报告。第三季度&#xff0c;百度实现营收325.4亿元&#xff0c;同比增长2%&#xff1b;归属百度的净利润&#xff08;non-GAAP…

在线杂志小程序开发,开启在线阅读时代

互联网技术的快速发展&#xff0c;让人们越来越依赖从网络上查看各种新闻资讯。传统的纸质杂志已经很难顺应时代的发展脚步&#xff0c;但是人们对于杂志的需求并没有减少。因此为了更好的满足众多读者对于杂志的需求&#xff0c;开发在线杂志小程序是十分必要的。在线杂志阅读…

时光倒流-第12届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第88讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

医院预约小程序源码,挂号陪护就医功能,提供全方位服务

随着人口老龄化形式加剧&#xff0c;年轻人工作压力大&#xff0c;没有闲余时间陪伴父母老人&#xff0c;因此针对解决独自去医院排队以及现代化设备需要等要求&#xff0c;而衍生出来的一个新型行业-挂号陪护。医院预约小程序源码开发的出现无非就是解决了这一难题&#xff0c…

教培行业迎来重大变局,三大方向或成新机遇

“双减”政策落地&#xff0c;教培行业迎来重大变局。校内教育深化改革正在路上&#xff0c;而学科类机构或将踏上转型之路&#xff0c;结合政策和市场来看&#xff0c;素质教育类、职业教育类、教育数字化3大方向或成新机遇。 “双减”的总体思路是什么呢&#xff1f; 教育部有…

[附源码]计算机毕业设计SpringbootON-FIT

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

QGIS下载在线地图(Google 卫星、esri 卫星)

前言 国内外有很多在线地图下载软件&#xff0c;但功能单一&#xff0c;基本上只能下载数据&#xff0c;无法做GIS分析&#xff0c;且多为收费&#xff0c;即便是免费&#xff0c;也多少有所限制。 在QGIS中&#xff0c;可以完全免费且迅速下载在线地图&#xff0c;首先请看阅…

Kafka集群环境的部署

Kafka集群环境的搭建一、Kafka集群二、搭建两台服务器2.1、 zookeeper部署2.2、 启动1号机器的broker2.3、 启动2号机器的broker2.4、查看kafka集群2.5、测试集群总结后言一、Kafka集群 二、搭建两台服务器 笔者的两台服务器IP&#xff1a; 服务器IP1号192.168.11.592号192.1…

matplotlib你真的明白plt,fig和ax吗

你真的明白plt&#xff0c;fig和ax吗&#xff1f; plt系列接口是用来模仿MATLAB的风格的。如果用户熟悉MATLAB&#xff0c;还是建议以plt为主的。对于基本的画图&#xff0c;plt系列足够了。 个人觉得&#xff0c;真正不合适的用法&#xff0c;反而是各种混淆plt接口和其它更细…

单目相机模型

针孔相机模型 针孔相机模型是实际研究中最常用的模型。针孔是一个中间有一个小孔的假想墙壁&#xff0c;光只能从小孔通过。 fff是摄像机焦距&#xff0c;ZZZ是摄像机到物体的距离&#xff0c;XXX是物体长度&#xff0c;是图像平面上的物体长度。由相似三角形可得&#xff1a…

护眼灯真的可以保护眼睛吗?市面上的护眼台灯到底是不是智商税

护眼灯能不能保护眼睛&#xff0c;护眼灯是不是智商税&#xff0c;这是很多人一直以来都有的疑惑&#xff0c;其实啊&#xff0c;这并不难判断&#xff0c;直接入手体验一下就知道了&#xff0c;有没有护眼效果&#xff0c;照明体验是否舒适&#xff0c;一试便知。 护眼灯怎样…

Java解决鸡兔同笼问题

1 问题 利用java程序&#xff1a;输入鸡和兔的总数和总腿数&#xff0c;来计算兔子和鸡的各个数量。 2 方法 import java.util.Scanner; /** * 已知鸡和兔的总数量为n,总腿数为m。 * 输入n和m,依次输出鸡和兔的数目&#xff0c; * 如果无解&#xff0c;则输出“No answer” */ …

[漏洞复现]Text4shell(CVE-2022-42889)

文章目录简介影响版本环境搭建漏洞复现漏洞修复参考简介 Apache Commons Text 项目实现了一系列关于文本字符串的算法&#xff0c;专注于处理字符串和文本块。10月13日&#xff0c;Apache发布安全公告&#xff0c;修复了Apache Commons Text中的一个远程代码执行漏洞&#xff…

GJB 5000B简介

“软件定义装备”是武器装备信息化职能化发展的比如趋势,J用软件在信息化战争和J事智能化进程中起着基础性决定性作用。 1、GJB 5000由来 1991年 推出CMM 目的:用来衡量组织软件综合能力 2000年,SEI发布CMMIV1.0(Capability Maturity Model Integration)能力成熟度模型集…

「低碳」不是特步的解药

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 文|螳螂观察 作者|叶小安 一双跑鞋就能减少碳排放424克&#xff0c;相当于回收16个饮料瓶。 这样一双低碳跑鞋&#xff0c;你会购买吗&#xff1f; 今年进博会上&#xff0c;特步带来了首款Mass Balance低碳环保概…

资本赋能,跨境电商Starday逐鹿年终场

国内巨头很早就看到跨境电商行业的发展前景了&#xff0c;最有代表性的就是阿里巴巴旗下的全球速卖&#xff0c;其在2012年就开始布局并开展跨境电商业务了&#xff0c;这些年来&#xff0c;诸如字节跳动、京东、拼多多等国内电商巨头纷纷跟上阿里巴巴步伐&#xff0c;进军跨境…

Scrapy基本概念——Scrapy shell

Scrapy shell是一个交互式shell&#xff0c;可以在不运行Spider的情况下&#xff0c;测试和调试自己的数据提取代码。事实上&#xff0c;Scrapy shell可以测试任何类型的代码&#xff0c;因为它本就是一个常规的Python shell。 一、Scrapy shell的使用 1、启动Scrapy shell …

【iMessage苹果家庭】共享推软件设备安装创作AppleScript增加了iMessage群应用会得到一个硬件token

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

计算机图形学-算法总结

文章目录计算机图形学-算法总结一、直线转换1、DDA算法2、中点法3、Bresenhan算法二、圆1、中点Bresenham画圆算法2、椭圆的中点Bresenham算法计算机图形学-算法总结 一、直线转换 1、DDA算法 Δyyn−y0Δxxn−x0ε1max(∣Δx∣,∣Δy∣)\Delta yy_n-y_0 \\ \Delta xx_n-x_0\…