白话说编程之java线程

  • 线程和进程:
    • 进程:
    • 线程:
    • 线程和进程的区别:
  • 详解多线程:
    • 并发
      • 为什么使用并发
      • 并发的执行原理
    • 并行
  • 线程的五种状态:
    • 创建状态:
    • 就绪状态:
    • 运行状态:
    • 阻塞状态:
    • 死亡状态:
  • 线程的创建方式:
    • 继承Thread
    • 实现Runnable
    • 匿名内部类方式
    • 迷惑问题
      • 继承THread类方法和实现Runnable接口 这两种方式选择哪一种好呢?
      • 继器启动线程是调用run方法还是start方法
  • 线程的分类:
      • 用户线程(也叫前台线程):
      • 守护线程(也叫后台线程):
    • 分享一波:程序员赚外快-必看的巅峰干货

线程和进程:

在说多线程之前,我们先来研究一下线程,说到线程,我们又不得不说到进程,因为很多初学者会把线程和进程分不清,搞混淆。

进程:

是操作系统系统运行的最小单元。怎么理解这句话,可以这样去对比,相信大家都见过积木玩具,可以搭建成很多的大型成品(操作系统Windows/Linux等等),而每一个积木都是组成这个成品的一个组件(也就是进程单元)这是操作系统和进程的关系(操作系统的组成很复杂,不是像积木简单的组合就能完成的,但是最底层原理我们可以这么想象是没有问题的)。

线程:

线程是一组指令的集合,它可以独立的运行在一个进程里。关于指令的集合:就是指我们编程里写的一个类,里面用到的关键字、方法名、变量名等等都是指令(你们可以这样去理解,完全没有问题,这里声明一下真正的指令是jvm编译成.class文件后,.class中的二进制码才是真正的指令,但是二进制码对于人类来说太多太难记,所以就用关键字来代表二进制的含义)。在这里我们又可以把线程去当成一个积木,而进程是一个个积木所组成的成品。

线程和进程的区别:

通过上面的例子,不难理解进程和线程之间的关系,进程包含线程,线程是进程的一个单元。所以在这里我们要注意一下,在进程中至少包含一个线程(主线程)。(这样讲,一个积木都没有还会有成品吗)

总结:进程是所有线程的集合,每一个线程是进程中的一条执行路径。

详解多线程:

在上面的例子中,我们知道线程和进程的区别,对于多线程的具体作用我们在这里详细解释。

并发

并发:多个线程在一个单核cpu上进行资源抢占并运行,就是并发。
多线程在cpu中是并发运行的(下面会详细解释并发,还有和并行的区别)
首先我们要知道在cpu(这里指的是单核cpu)中在某一个时间片,只能有一个线程在cpu中运行。一个cpu在同一时间只能执行一个线程。

为什么使用并发

在一个进程中有多个线程需要执行,这些线程会抢占cpu的时间片来运行自身。有人会问,为什么不等一个线程执行完之后再去执行另一个线程呢?思考一下,我们在使用电脑的时候,可以同时看文档,听音乐。如果cpu设计成一个线程执行完之后再去执行另一个线程,你就只能听完音乐,在去看文档,在听音乐的过程中你的鼠标都移动不了(鼠标也是一个单独线程),你们觉得这样的体验好吗,所以cpu肯定不能这样设计。

并发的执行原理

操作系统是以抢占式的方法来调度线程的(也有其他方法,我们目前先学这一种)。就是线程自己去强cpu的资源,谁先抢到谁就在cpu上运行一个时间片(这个时间片很短很短)。这里的线程会有优先级的特点,优先级高的线程抢到cpu的概率大,概率大,概率大(是概率大,不代表一定能抢到)运行完成之后释放cpu资源,回去重新抢占cpu。因为运行的时间很短,所以在人为感官上觉得这些线程始再同时运行的。
其实上面多个线程抢占cpu资源就是多线程的并发。

注意:这里是一个cpu。随着需求的不断增高,科技的不断发展,单核cpu的性能已经不能满足效率。于是就出现了多核cpu,也就出现了并行

并行

并行:在同一时间点,多个线程同时运行在多核cpu的多个核上,这叫并行。和并发不同的是:同一时间,在并行中,线程可以同时运行,而并发则只能有一个线程运行。

线程的五种状态:

创建状态:

当用new操作符创建一个线程时, 例如new Thread®,线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码

就绪状态:

一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。
处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。

运行状态:

当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.

阻塞状态:

线程运行过程中,可能由于各种原因进入阻塞状态:
1>线程通过调用sleep方法进入睡眠状态;
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;

死亡状态:

有两个原因会导致线程死亡:
1> run方法正常退出而自然死亡,
2> 一个未捕获的异常终止了run方法而使线程猝死。
为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.

如图所示:

线程的创建方式:

继承Thread

实现Runnable

匿名内部类方式


上面只要会继承THread类方法和实现Runnable接口这两种就行,还有其他的线程池创建等等,在后面的章节说

迷惑问题

继承THread类方法和实现Runnable接口 这两种方式选择哪一种好呢?

在java语言中,有一个特点,就是单继承,多实现。实现了接口还可以继续继承,继承了类不能再继承。所以一般情况下使用实现Runnable会有更好的拓展性。

继器启动线程是调用run方法还是start方法

Run方法仅仅只是线程所要执行的代码块部分,如果调用run方法,就和调用其他普通方法一样,从上到下,顺序执行。没有了多线程的特点。所以使用start方法使线程进入就绪状态。

线程的分类:

用户线程(也叫前台线程):

用户自定义创建的线程,用户线程的状态不受其他线程的影响。别的线程挂了就挂了,影响不到他,因为他们是互相独立的。

守护线程(也叫后台线程):

守护线程受用户线程的影响,当用户线程销毁后,守护线程也会跟着销毁。比如GC

分享一波:程序员赚外快-必看的巅峰干货

白话说编程之java线程相关推荐

  1. Java并发编程之Java线程池

    Java线程池: 线程池的核心配置参数: //线程等待任务的超时时间,当线程池的线程个数超过corePoolSize时生效,当线程等待任务的时间超过keepAliveTime时,线程池会停止超过cor ...

  2. JUC并发编程之Java线程(二)

    二.Java线程 2.1 创建和运行线程 方法一:Thread创建线程方式: 继承Thread类 匿名内部类方式 public class CreateThread01 {public static ...

  3. 并发编程之 Executor 线程池原理与源码解读

    并发编程之 Executor 线程池原理与源码解读 线程是调度 CPU 资源的最小单位,线程模型分为 KLT 模型与 ULT 模型,JVM使用的是 KLT 模型.java线程与 OS 线程保持 1:1 ...

  4. Java 并发编程之 ThreadLocal 线程局部变量

    ThreadLocal 通过get和set方法,为每个使用该变量的线程提供一个独立的副本,使得线程安全的共享某个变量:使用 set 方法设置变量后,一定要记得及时使用 remove 方法清理,否则多线 ...

  5. 并发编程之Java内存模型

    在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么.然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性. 为什么要有内存模型 在计算机中,所有的运算操 ...

  6. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

  7. 【MySQL 数据库】JDBC 编程之 Java 连接 MySQL

    文章目录 1. 数据库编程的基础条件 2. Java 的数据库编程:JDBC 3. JDBC 访问数据库的层次结构 4. MySQL 数据库操作介绍 5. MySQL 驱动包的下载及添加到项目 6. ...

  8. 并发编程之Executor线程池原理与源码解读

    1. 线程池 "线程池",顾名思义就是一个线程缓存,线程是稀缺资源,如果被无限制的创建,不 仅会消耗系统资源,还会降低系统的稳定性,因此Java中提供线程池对线程进行统一分配. 调 ...

  9. java声明变量简单程序_零基础学编程之java变量

    01使用变量的意义 变量相当于自然语言中的代词,代词具有代替.指示作用,比如每个人的姓名,代表的就是真实的一个个体.如果没有名字,我们在交流的时候,讨论某一个人就需要说:身高1米75,单眼皮,双下巴的 ...

最新文章

  1. K近邻算法KNN的简述
  2. java dateformat类_JAVA--常量池,Date类,SimpleDateFormat类与Calendar类
  3. std::vector使用简介
  4. Observer模式在J2EE中的实现
  5. 20145234黄斐《网络对抗技术》实验八、Web基础
  6. 蚂蚁动态卡片,让App首页实现敏捷更新
  7. stringstream的基本用法
  8. ​【月报】Java知音的三月汇总
  9. Julia: “.juliarc.jl” 的妙用:设置IDE启动时,自动运行某文件或某行命令
  10. iOS关于上传iTunes store一直卡住终极解决方案
  11. AltiumDesigner14.3.X下载安装破解教程
  12. 海思HI3519V101 SDK详细编译过程
  13. ubuntu 16.04 单用户____修改忘记密码
  14. linux从零基础开始
  15. XMind教程详解之畅通使用
  16. 【微信小程序】Java岗面试12家大厂成功跳槽
  17. 怎么用python编写程序计算标准差_自学生信Python(第五天)|如何计算标准差?...
  18. c语言不能输出字符A的语句的是,以下不能输出字符a的语句是( )。
  19. B-样条基函数:定义 (B-spline Basis Functions: Definition)
  20. simple-uploader.js 文档

热门文章

  1. 网络学习云平台 计算机基础应用,计算机应用基础网络自主学习平台使用说明.doc...
  2. java for新循环_Java 8 新语法习惯 (for 循环的函数替代方案)
  3. oracle java存储过程返回值_java程序调用Oracle 存储过程 获取返回值(无返回,非结果集,结果集)...
  4. codeforces B. Friends and Presents(二分+容斥)
  5. python中multiply函数_python中numpy库内multiply()、dot()和 * 三种乘法运算的区别小计...
  6. 去哪里找与计算机相关的外文,找计算机相关的外文翻译
  7. mysql修改表的字段_mysql修改表字段学习笔记
  8. mysql 5.5 主从同步问题_MySQL 5.5 主从复制异步、半同步以及注意事项详解
  9. python split函数 空格_python上手--10行代码读懂红楼梦
  10. python出现traceback什么意思_python-异常处理 traceback获取详细异常