将笔者学习多线程的一些笔记发出来,方便读者学习,以前总是索取,不知道回报,希望我的一些经历经验,会帮助到正在学习的你,也希望大家能一起讨论,共同学习。(如果有问题,可以留言,笔者会尽快处理,如果有出错,希望您能指出,大家共同学习)
1、 什么叫做线程
线程就是轻量级的进程,是程序执行的最小单位。
2、 为什么需要多线程
多线程其实就是作弊,如果单个cpu足够快的情况下,根本不需要多线程,单线程即可解决所有问题,而且不会带来多线程执行的一些不可预知的问题。但是硬件已经发展到一定的瓶颈了,只能通过增加cpu的数量(cpu的核数),才能保证足够的运算量。于是便有了多线程。
3、 并发和并行
其实这是两个概念,但是我们经常把它搞混。他们都可以表示两个或者多个任务一起执行只是偏重点不通。
并发:多个任务交替执行,实质是多个任务是串行的。
并行:多个任务同时执行。
我们讨论的其实都是并行。
4、 什么情况会需要并行
并行目前只有两个领域用得到,图像处理和服务端编程,并且很广泛,其他领域其实真的没有必要使用。(这不是笔者说的,这话其实是linus说的,如果你不知道linus是谁,那么他的名字看着与linux差不多,你也能联想到了吧,没错,是他提出了linux的原型,并一直致力于linux系统的推广和发展。)
5、 同步和异步
这两个概念,我相信,面试过多线程的面试者一定都会被问到。而且这两个概念在多线程中使用也真的是非常的广泛。
同步:同步便是调用方法,必须要等到被调用方法执行完成,才能继续执行,也就是说,调用方法是被阻塞的。
异步:这是调用方法不需要等到被调用方法执行完成,就可以继续执行。最常见的便是生产者和消费者模式。
6、 多线程中比较重要的概念
这些概念都是笔者学习工作中常遇到的一些比较重要的概念。
原子性:指的是一个操作是不可以被中断的。注意原子性不能完全解决多线程的并发问题,必须和锁配合使用,才能保证线程可以正确的执行,这个问题,笔者会在后面详细说明。
可见性:指一个线程修改了变量的值,其他使用这个变量的线程是否能够立刻知道这个修改。比较常用的便是volatile修饰符。
有序性:程序在执行的时候,虚拟机可能会对指令进行重排,重排后的指令未必与之前的一致,这也是导致并发问题很复杂的原因。(至于为什么要有指令重排,主要就是为了保证执行效率,再详细的原因,可以去读一读jvm相关的文章,这里不过多赘述)。
7、 如何创建一个线程
Java中有两种方式创建线程:
Ø 继承Thread类,重写run方法。
Ø 实现Runnable(Callable)接口,实现run方法。
至于Runnable和Callable的不同:Callable使用的是Future模式,可以有返回值,也可以处理一些异常。Runnable则不会有返回值。(Future模式,后续会详细讲解)。
使用哪种方式比较好,提醒你一点,java中只能继承一个类,但是可以实现多个接口,笔者只能帮你这么多了。