3 多线程的使用方式
==========
3.1 继承 Thread类
可以看到程序在交替执行,但是最终都会执行到98。
3.2 实现Runnable接口
依旧可以看到程序在交替执行,但是最终都会执行到98。
3.3 继承实现Callable接口
这里需要说明的是实现Callable接口,必须重写call()方法,并且要用到FutureTask类,这里先不做介绍,等后面更新线程池再细讲。
3.4 使用线程池例如用Executor框架
这部分暂不介绍。后面更新线程池和Executor会详细介绍。
4 使用多线程一定快吗?
============
答:不一定,因为多线程会进行上下文切换,上下文切换会带来开销。
4.1 什么是上下文切换?
对于单核 CPU,CPU 在一个时刻只能运行一个线程,当在运行一个线程的过程中转去运行另外一个线程,这个叫做线程上下文切换(对于进程也是类似)。线程上下文切换过程中会记录 程序计数器、CPU 寄存器 的 状态等数据。
4.2 如何减少上下文切换?
4.2.1 减少线程的数量
由于一个CPU每个时刻只能执行一条线程,而傲娇的我们又想让程序并发执行,操作系统只好不断地进行上下文切换来使我们从感官上觉得程序是并发执的行。因此,我们只要减少线程的数量,就能减少上下文切换的次数。
然而如果线程数量已经少于CPU核数,每个CPU执行一条线程,照理来说CPU不需要进行上下文切换了,但事实并非如此。
4.2.2 控制同一把锁上的线程数量
如果多条线程共用同一把锁,那么当一条线程获得锁后,其他线程就会被阻塞;当该线程释放锁后,操作系统会从被阻塞的线程中选一条执行,从而又会出现上下文切换。
因此,减少同一把锁上的线程数量也能减少上下文切换的次数。
4.2.3 采用无锁并发编程
需要并发执行的任务是无状态的:HASH分段
所谓无状态是指并发执行的任务没有共享变量,他们都独立执行。对于这种类型的任务可以按照ID进行HASH分段,每段用一条线程去执行。
需要并发执行的任务是有状态的:CAS算法
如果任务需要修改共享变量,那么必须要控制线程的执行顺序,否则会出现安全性问题。你可以给任务加锁,保证任务的原子性与可见性,但这会引起阻塞,从而发生上下文切换;为了避免上下文切换,你可以使用CAS算法, 仅在线程内部需要更新共享变量时使用CAS算法来更新,这种方式不会阻塞线程,并保证更新过程的安全性。
5 使用多线程的缺点:
===========
5.1 上下文切换的开销
当 CPU 从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为“上下文切换”。CPU 会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。上下文切换并不廉价。如果没有必要,应该减少上下文切换的发生。
5.2 增加资源消耗
线程在运行的时候需要从计算机里面得到一些资源。 除了 CPU,线程还需要一些 内存来维持它本地的堆栈。它也需要 占用操作系统中一些资源来管理线程。
5.3 编程更复杂
在多线程访问共享数据的时候,要考虑 线程安全问题 。
6 线程安全
======
6.1 线程安全定义
一个类在可以被多个线程安全调用时就是线程安全的。
6.2 线程安全分类
线程安全不是一个非真即假的命题,可以将共享数据按照安全程度的强弱顺序分成以下五类:
不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。
6.2.1. 不可变
不可变(Immutable)的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何的线程安全保障措施,只要一个不可变的对象被正确地构建出来,那其外部的可见状态永远也不会改变,永远也不会看到它在多个线程之中处于不一致的状态。
不可变的类型:final 关键字修饰的基本数据类型;String ;枚举类型;Number 部分子类,如 Long 和 Double 等数值包装类型,BigInteger 和 BigDecimal 等大数据类型。但同为 Number 的子类型的原子类 AtomicInteger 和 AtomicLong 则并非不可变的。
6.2.2 绝对线程安全
不管运行时环境如何,调用者都不需要任何额外的同步措施。
6.2.3 相对线程安全
相对的线程安全需要保证对这个对象单独的操作是线程安全的,在调用的时候不需要做额外的保障措施,但是对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。
6.2.4 线程兼容
线程兼容是指对象本身并不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全地使用,我们平常说一个类不是线程安全的,绝大多数时候指的是这一种情况。Java API 中大部分的类都是属于线程兼容的,如与前面的 Vector 和 HashTable相对应的集合类 ArrayList 和 HashMap 等。
Spring是Java程序员的《葵花宝典》,其中提供的各种大招,能简化我们的开发,大大提升开发效率!目前99%的公司使用了Spring,大家可以去各大招聘网站看一下,Spring算是必备技能,所以一定要掌握。
CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】
目录:
部分内容:
它的目标是简化Spring应用和服务的创建、开发与部署,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用的微服务功能,可以和spring cloud联合部署。
Spring Boot的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式。
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
目录:
部分内容:
xLT6-1630720162141)]
[外链图片转存中…(img-PitmTupP-1630720162141)]
目录:
[外链图片转存中…(img-E93xVRC9-1630720162142)]
[外链图片转存中…(img-OnP53DrX-1630720162142)]
[外链图片转存中…(img-6A53C2cz-1630720162143)]
部分内容:
[外链图片转存中…(img-cMUt0tNf-1630720162144)]
[外链图片转存中…(img-yj4FW7jF-1630720162144)]