白话说编程之java线程
线程和进程:
在说多线程之前,我们先来研究一下线程,说到线程,我们又不得不说到进程,因为很多初学者会把线程和进程分不清,搞混淆。
进程:
是操作系统系统运行的最小单元。怎么理解这句话,可以这样去对比,相信大家都见过积木玩具,可以搭建成很多的大型成品(操作系统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线程的更多相关文章
- QT核心编程之Qt线程 (c)
QT核心编程之Qt线程是本节要介绍的内容,QT核心编程我们要分几个部分来介绍,想参考更多内容,请看末尾的编辑推荐进行详细阅读,先来看本篇内容. Qt对线程提供了支持,它引入了一些基本与平台无关的线程类 ...
- 三、VIP课程:并发编程专题->01-并发编程之Executor线程池详解
01-并发编程之Executor线程池详解 线程:什么是线程&多线程 线程:线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系 ...
- python并发编程之Queue线程、进程、协程通信(五)
单线程.多线程之间.进程之间.协程之间很多时候需要协同完成工作,这个时候它们需要进行通讯.或者说为了解耦,普遍采用Queue,生产消费模式. 系列文章 python并发编程之threading线程(一 ...
- python并发编程之threading线程(一)
进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...
- [转]c++多线程编程之pthread线程深入理解
多线程编程之pthread线程深入理解 Pthread是 POSIX threads 的简称,是POSIX的线程标准. 前几篇博客已经能给你初步的多线程概念.在进一 ...
- 多线程之Java线程阻塞与唤醒
线程的阻塞和唤醒在多线程并发过程中是一个关键点,当线程数量达到很大的数量级时,并发可能带来很多隐蔽的问题.如何正确暂停一个线程,暂停后又如何在一个要求的时间点恢复,这些都需要仔细考虑的细节.在Java ...
- 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则
前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...
- 并发编程之 Java 三把锁
前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...
- 并发编程之Java内存模型
在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么.然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性. 为什么要有内存模型 在计算机中,所有的运算操 ...
随机推荐
- Layui select下拉框改变之 change 监听事件(转)
在layui中使用 jquery 触发select 的 change事件无效 使用layui.use监听select事件 <select lay-filter="demo" ...
- .net 4.0 以下HttpWebRequest Header 修改hosts方法
.net 4.0 以下HttpWebRequest Header 修改hosts方法 特此记录 public class CusteredHeaderCollection : WebHeaderCol ...
- Spring框架——IOC 自动装载
IOC自动装载有两种形式 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- CVE-2019-3396:Confluence未授权模板注入_代码执行
title: Confluence未授权模板注入/代码执行(CVE-2019-3396) tags: [poc,cve] 简介 Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企 ...
- 试译 Understanding Delta-Sigma Modulators
接触Σ-Δ调制的时候发现国内有关的资料比较匮乏,因为缺乏了解还有一些人把其中的原理吹得神乎其神难以理解.其实Σ-Δ调制的原理是很简单.逻辑上很自然的,可以定性理解成传统ADC/DAC量化的是 ...
- 用sort 排序
这两天看了一个比较好的sort总结,所以转载了一下 阅读目录 1.sort 2.sort简介 3.sort扩展 1.sort 使用:#include <algorithm> using ...
- 概率-Knight Probability in Chessboard
2018-07-14 09:57:59 问题描述: 问题求解: 本题本质上是个挺模板的题目.本质是一个求最后每个落点的数目,用总的数目来除有所可能生成的可能性.这种计数的问题可以使用动态规划来进行解决 ...
- css清除浮动影响
将清除浮动代码添加到重置样式表中,随时可以调用 }}.clearfix:after{clear:both} 给需要清除浮动影响的元素添加class名 --- clearfix 例: <!-- c ...
- 分享一个超级好用的SM图床
分享一个超级好用的SM图床 大家都知道我是一个喜欢sm Markdown的人,但是Markdown有个很不方便的地方,就是图片的插入,一般用Markdown编辑器(我用的是Typora)直接插入图 ...
- effective-java学习笔记---注解优于命名模式39
命名模式的缺点有以下三点:(在第 4 版之前,JUnit 测试框架要求其用户通过以 test[Beck04] 开始名称来指定测试方法) 1.拼写错误导致失败,但不会提示. 2.无法确保它们仅用于适当的 ...