本文系作者 chaoCode原创,转载请私信并在文章开头附带作者和原文地址链接。

违者,作者保留追究权利。

前言

并发编程在我们日常开发中是时时刻刻都有在用的,只不过大部分的代码底层已经帮我们去做了一些并发编程的安全处理,但是还是有很多情况下需要我们自己去控制,所以我们需要去了解学习并发编程,那么我们一步一步深入的开始学习。

认识java里的线程

Java 程序天生就是多线程的

一个 Java 程序从 main()方法开始执行,然后按照既定的代码逻辑执行,看 似没有其他线程参与,但实际上 Java 程序天生就是多线程程序,因为执行 main() 方法的是一个名称为 main 的线程。

[6] Monitor Ctrl-Break //监控 Ctrl-Break 中断信号的

[5] Attach Listener //内存 dump,线程 dump,类信息统计,获取系统属性等

[4] Signal Dispatcher // 分发处理发送给 JVM 信号的线程

[3] Finalizer // 调用对象 finalize 方法的线程

[2] Reference Handler//清除 Reference 的线程

[1] main //main 线程,用户程序入口

Java线程的创建方式

Thread源码有说明Java线程创建方式,一共有两种。

1.继承Thread类

2.实现Runable接口

当然网上也有人说有第三种,通过实现Callable和Future接口来创建线程。

在Thread类源码中,给出了说明和线程创建方式示例:

Thread 才是 Java 里对线程的唯一抽象,Runable、Callable、Future 只是对任务(业务逻辑) 的抽象。

因此,出现了多种线程创建方式的说法。

1.继承Thread

  • [1] 定义Thread类的子类,并重写该类的run()方法,run()方法被称为线程执行体。
  • [2] 创建Thread子类的实例,即创建线程对象。
  • [3] 调用线程对象的start()方法启动该线程。

2.实现Runnable接口

Thread提供一个带参数的构造方法,我们通过实现Runnable接口再借用这个构造方法就可以获取到根据我们自定义的任务的Thread对象

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

  • [1] 定义Runnable接口的实现类,并重写该接口的run()方法。
  • [2] 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
  • [3] 调用线程对象的start()方法来启动该线程。

3.使用Callable和Future

实质也是使用Thread(Runnable target)构造方法,我们通过实现Callable接口实现一个带返回值的任务,然后通过FutureTask类来包装Callable对象,FutureTask这个类实现了RunnableFuture这个接口,但是RunnableFuture这个接口继承了Runnable接口,所以就可以用这个构造方法就可以获取到根据我们自定义的任务的Thread对象。





  • [1] 创建Callable接口的实现类,并实现call()方法,该call()方法作为线程执行体,且该call()方法有返回值。
  • [2] 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该Future Task对象封装了Callable对象的call()方法的返回值。
  • [3] 使用Future Task对象作为Thread对象的target创建线程对象。
  • [4] 调用线程对象的start()方法来启动该线程。
  • [5] 调用Future Task对象的get()方法来获得子线程执行结束后的返回值。

创建线程的三种方式对比

实现Runnable接口和实现Callable接口的方式基本相同,只是Callable接口里定义的方法有返回值,可以声明抛出异常,大体上可以归结为一大类。这种方式与继承Thread方式之间的主要差别是采用实现Runnable,Callable接口创建多线程

1、线程类只是实现了Runnable接口或Callable接口,也可以继续实现别的接口,还可以继承其他类。

2、多个线程可以共享同一个Runnable对象,非常适合多个相同线程来处理同一份资源的情况(面向对象)。

3、如果要访问当前线程,必须使用Thread.currentThread()方法,比较复杂。

采用继承Thread类的方式创建线程:

1、因为线程类已经继承了Thread类,所以不能再继承其他父类。

2、如果要访问当前线程,直接使用this即可获得。

通过上面的分析我们发现创建线程的本质就如源码所写那样有两种方式。一个是继承Thread类,一种是实现Runnable接口。

通过对比我们发现,通过接口去创建线程的方式会让我们代码有更大的容错率,有更大的变通空间以及更加的灵活,同时也减少了程序之间的耦合度,毕竟六大原则中的依赖倒置原则的中心思想就是面向接口编程。所以推荐使用实现接口的方式来创建线程。

感谢诸君的观看,文中如有纰漏,欢迎在评论区来交流。如果这篇文章帮助到了你,欢迎点赞关注。

并发编程——认识java里的线程的更多相关文章

  1. java并发编程笔记(三)——线程安全性

    java并发编程笔记(三)--线程安全性 线程安全性: ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现 ...

  2. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  3. Java并发编程(您不知道的线程池操作)

    Java并发编程(您不知道的线程池操作) 这几篇博客,一直在谈线程,设想一下这个场景,如果并发的线程很多,然而每个线程如果执行的时间很多的话,这样的话,就会大量的降低系统的效率.这时候就可以采用线程池 ...

  4. Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

    目录 引言 四种线程池 newCachedThreadPool:可缓存的线程池 newFixedThreadPool:定长线程池 newSingleThreadExecutor:单线程线程池 newS ...

  5. 【Java并发编程】之二:线程中断

    [Java并发编程]之二:线程中断 使用interrupt()中断线程 ​ 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一 ...

  6. java并发编程笔记(七)——线程池

    java并发编程笔记(七)--线程池 new Thread弊端 每次new Thread新建对象,性能差 线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM 缺 ...

  7. java并发编程笔记(五)——线程安全策略

    java并发编程笔记(五)--线程安全策略 不可变得对象 不可变对象需要满足的条件 对象创建以后其状态就不能修改 对象所有的域都是final类型 对象是正确创建的(在对象创建期间,this引用没有逸出 ...

  8. 小谈Java里的线程

    今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...

  9. 【并发编程】Java并发编程传送门

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. [并发编程系列博客传送门](https://www.cnblogs.com/54 ...

随机推荐

  1. JAVA实现按列表中元素的时间字段排序

    JAVA代码实现按列表中元素的时间字段排序 导语: 工作中遇到一个问题,调用第三方接口返回的数据没有按时间倒序排列,测试说要加,然后在网上找到一个解决办法,这里记录一下 需求: 如下图列表,按生日进行 ...

  2. JavaScript与服务端进行数据交互的方式

    XMLHttpRequest XHR是项古老的技术,不同的浏览器厂商对其实现方式不同,例如有些浏览器只支持onload事件处理器,有些只支持onreadystatechange事件处理器. 发送Get ...

  3. @Autowired报错原因分析和4种解决方案!

    上图的报错信息相信大部分程序员都遇到过,奇怪的是虽然代码报错,但丝毫不影响程序的正常执行,也就是虽然编译器 IDEA 报错,但程序却能正常的执行,那这其中的原因又是为何? ​ 报错原因分析 报错的原因 ...

  4. Zabbix5.0微信报警

    3.1.注测企业微信: 3.2.企业微信注册成功后进入后台管理: 3.3.添加一个部门,并记住部门id: #我这里添加的子部门ID为2 3.4.添加一个用户到上面创建的部门里面(这里采取直接将管理员添 ...

  5. 使用Flash Builder 4.6出现 新建配置 失败 java.lang.NullPointerException错误

    当看到这个错误的时候有点莫名奇妙的感觉,随后的第一反应是: 这跟我前些天安装的java的jre 1.8 有没有关联性.修改了设定,方法如下 "运行" -> "外部工 ...

  6. webpack(1)安装环境与解决环境问题

    前言 如果我们需要使用webpack,就需要依赖node环境 nvm node npm webpack@cli webpack nvm安装 nvm是一个用来管理node版本的工具.我们之所以需要使用n ...

  7. Redis 底层数据结构之整数集合

    文章参考:<Redis 设计与实现>黄建宏 整数集合 整数集合时集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合数量不多时,就会使用整数集合 typedef struct i ...

  8. [心得]docker学习笔记

    1. docker是什么??? (1) docker是一台类似虚拟机的功能, 内部由一个个镜像组成, 镜像里可以运行容器, 而这个容器可以是任何东西, 比如mysql, 比如tomcat等等, 它的目 ...

  9. Mybatis学习(6)与Spring MVC 的集成

    前面几篇文章已经讲到了mybatis与spring 的集成.但这个时候,所有的工程还不是web工程,虽然我一直是创建的web 工程.今天将直接用mybatis与Spring mvc 的方式集成起来,源 ...

  10. SpringMVC(3)URL请求到Action的映射规则

    在SpringMVC(2)经典的HelloWorld实现我们展示了一个简单的get请求,并返回了一个简单的helloworld页面.本篇我们来学习如何来配置一个action的url映射规则. 在Spr ...