java基础系列之多线程

≯℡__Kan透↙ 提交于 2019-11-28 20:13:33

之前对多线程这块一直不是很懂,现在看了一端时间的书与资料,写一些自己的心得体会吧

  • 并发与并行

并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。

并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

打个比方:并行就是一个乐队在同一时间一起演奏 , 并发 就是一个人很短的时间内又弹钢琴又打鼓,只不过是他速度很快,感觉有多个人在演奏而已;

在这里插入图片描述

  • 线程与进程

进程:运行中的应用程序称为进程,拥有系统资源(cpu、内存)

线程:进程中的一段代码,一个进程中可以有多段代码。本身不拥有资源(共享所在进程的资源),线程是最小的执行单元,每个进程都至少拥有一个线程;

在java应用程序来说,一个web 服务就是一个进程,在linux 系统中,当程序开启时,我们需要手动 或自动的给它分配内存空间,是因为它其中的线程需要这些(程序计数器,堆区,栈区等等)才能跑起来。
关闭时,我们可以通过对应的命令来关闭它,那它所拥有的系统资源就会释放,它的线程也会停止。

举个栗子
公司=进程 ,码农=线程;
在公司中,我们敲代码需要公司提供办公地点工具(电脑,座位,工资等等),我们共享这些资源当谁需要时给谁使用,当公司倒闭时会将这些回收,我们码农没有作案工具自然就没有办法运作下去。

在这里插入图片描述

  • 线程的生命周期

在这里插入图片描述

  • 多线程

上面我们大致了解线程,接下来我们看看如何启动多个线程
创建线程的方式有三种:
1.继承Thread类 (不符合里氏代换原则)
2.实现Runnable 接口 相对于第一种推荐第二种
3.实现Callable接口,它有两个特点 一是可以通过call()获取返回值,二是call()方法可以抛出异常;

  • 什么情况下会有线程安全问题?

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

解决方案一般来说有四种;
1.数据单线程内可见
单线程是安全的,通过限制数据仅在单线程内可见,可以避免数据被其他线程篡改。最典型的就是线程局部变量,存储在独立虚拟机栈帧的局部变量表中,与其他线程没有关系。比如 ThreadLocal (要是感兴趣我会专门写一篇这个)

2.只读对象
只读对象是安全的,他的特性是允许复制,拒绝写入。只读对象需要使用private final修饰 避免继承及属性被中途修改,没有任何更新方法,返回值不能为可变对象;

3.线程安全类
比如StringBuffer 就是线程安全类,采用synchronized 关键字来修饰相关方法

4.同步与锁机制
需要自己在代码中实现, 通过加锁或同步代码块的方法等等

其实综上所述, 线程安全 要么只读 要么加锁。 在JDK中有提供对应的并发包 可以帮助我们实现(要是感兴趣我也会专门写一篇这个)

之前我朋友在面试时,被一个问题问倒了 ,单例模式是否线程安全? 这里篇幅有限就不在一一说明了,感兴趣的同学可以去看看,感觉这个写的还可以(https://www.cnblogs.com/sunnyDream/p/8011186.html
有讲到 双重锁 和volatile关键字。(volatile关键字可以禁止指令重排序)

图片及部分资料网上所得

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!