多线程的讲解

并发与并行:
并发:多个线程操作同一个资源,不是同时执行,而是交替执行,单核CPU交替执行时间间隔特别短
并发编程:指多个任务在一个时间段重复执行的结构
并发编程的三个特性:
1.原子性
原子操作:不可分割的操作,中间不会被其他线程打断,不需要同步操作
多个原子操作合起来就需要使用到同步
原子性指的是一次操作或者多个操作,要么全部执行,要么全部都不执行
例如:
int a = 10 ; //原子操作
a++; // 不是原子操作
int b = a; //不是原子操作
a = a+1; // 不是操作
2.可见性
当在一个线程中队某一共享变量进行了修改,那么另外的线程可以立即看到修改后的新值
3.顺序性
程序代码在执行过程中的先后顺序
单线程环境指令重排序不会影响最终的结果
如何实现高并发(提高系统的并发能力)
垂直扩展(硬件):
增强计算机的硬件性能:增加cpu核数,内存升级,磁盘扩容
提高系统的架构能力:使用cache提高效率
水平扩展(软件):
集群,分布式

并行:并行指的是同时执行,多核CPU,每一个线程使用一个单独CPU

线程与进程
线程:
线程是组成进程的基本单位,cpu调用的最小单位
进程:
进程是计算机上的独立的应用程序,资源分配的最小单位

两者区别:
1.内存空间
进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

2.安全性
多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

3.效率
线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式进行。

线程的状态及状态转换
线程六状态
1).New----Thread对象的状态,在没有start之前,该线程不存在时;
2).Running----一旦CPU选中了线程,那么此时该线程能够去执行自己的逻辑代码;
3).Runnable----Thread对象进入Runnable状态必须调用start方法,此时真正的在JVM中创建了一个线程,线程启动之后并不会立即去执行,该状态的线程位于可运行线程池中,等待操作系统的资源,比如:处理器 (在等待cpu的使用权;
4).WAITING/TIMED_WAITING----等待状态
5).Blocked----等待一个监视器锁进入到synchronized block/method,处理这个里面的逻辑代码在某一时刻只能允许一个线程执行,其他线程只能去等待,这种情况下,等待的线程处于Blocked状态,处于Blocked状态的线程获取到了监视器锁,则应该从Blocked状态转换到Runnable状态;
6).Terminated----该状态表示线程的最终状态,在该状态中线程不会切换到其他的状态,线程进入该状态,意味着线程的整个生命周期已经结束;
进入Terminated状态的情况
进入Terminated状态的三种情况:
1.线程运行正常结束
2.线程运行出错
3.JVM crash,导致所有线程结束

线程常用方法
1.start()
开启线程
2.sleep()
Thread.sleep() 使得当前线程进入指定毫秒数的休眠。休眠有一个重要特性,不会放弃monitor锁的使用权。jdk1.5之后,引入枚举TimeUnit
3.yield()
让步一次cpu时间片,只是对于cpu调度器的一个提示
4.joind()
在线程A中,join某个线程B,会使得线程A进入等待,直到线程B结束了自己的生命周期或者达到给定的时间,那么在此期间,线程A处于等待状态,join方法可以使得线程顺序执行
5.interrupt()
中断线程的方法
----Thread.sleep()
----Object.wait()
----Thread.join()
----Selector.wakeUp()

这些为可中断方法,不和interrupt方法同时使用(调用这些方法后,线程处于阻塞状态,如果另一线程调用被阻塞线程的interrupt方法,则会打断这个线程的阻塞状态,并会报错)
6.isInterrupted()
判断线程是否被中断
7.interrupted()
静态方法,底层调用isInterrupted方法,检测线程是否被中断
第一次调用interrupted方法会返回true,并且会立即擦除线程中的中断状态位,之后调用都会返回false

yield和sleep的区别
1)sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给优先级低的线程以运行的机会,而yield()方法只会给相同优先级或者更高优先级的线程以运行机会。
2)线程执行sleep()方法后会转入阻塞状态,所以,执行sleep()方法的线程在指定的时间内肯定不会被执行,而yield()方法只是使当前线程重新回到可执行状态,所以执行yield()方法的线程有可能在进入到可执行状态后马上又被执行。
3)sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常。
4)sleep()方法比yield()方法(跟操作系统)具有更好的可移植性。

各状态之间的转化:
在这里插入图片描述
synchronized详解
1:synchronized关键字:
防止线程干扰和内存一致性错误,如果一个对象对多个线程是可见的,那么对该对象的所有读/写都可以通过同步的方式来进行
Synchronized关键字提供了锁机制,能够去保证共享资源的互斥访问,解决数据不一致的问题
2:synchronized理解
2.1锁池与等待池
锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁(因为wait()方法必须出现在synchronized中,这样自然在执行wait()方法之前线程A就已经拥有了该对象的锁),同时线程A就进入到了该对象的等待池中。如果另外的一个线程调用了相同对象的notifyAIl()方法,那么处于该对象的等待池中的线程就会全部进入该对象的锁池中,准备争夺锁的拥有权。如果另外的一个线程调用了相同对象的notify()方法,那么仅仅有一个处于该对象的等待池中的线程(随机)会进入该对象的锁池.
3.monitor
一种同步机制/一个对象
所有的Java对象天生可以作为monitor
每一个对象自实例化之后都带有一把锁,这个锁称之为monitor锁/同步锁
monitor是线程私有的
4.monitor的结构:
Owner : 初始为NUll,如果有线程获取到monitor锁,Owner会保存线程唯一标识
EntryQ:阻塞所有试图获得monitor锁失败的线程
RcThis:blocked/Waiting在monitor上的所有线程个数
Nest:重入锁的个数
HashCode:保存对象的Hashcode
Candidate:用来避免不必要的阻塞或者额等待线程唤醒

synchronized锁升级分析
偏向锁
CAS指令:(Compare And Swap)cpu层面的原子性操作指令,该指令存在三个参数,第一参数是目标地址, 第二参数是值1,第三参数值2,指令会比较目标存储的值跟值1是否一致,如果一致目标地址会更新为新值,即值2。如果一个线程获得了锁,那么锁就会进入偏向模式,锁标识位为01,是否为偏向锁为1,当这次线程再次请求锁的时候,不需要做同步操作,直接省略锁的获取阶段,提高系统的性能。这种场合下可能不存在锁竞争锁竞争比较激烈的时候,偏向锁获取失败升级为轻量级锁
轻量级锁
轻量级锁所适应的线程交替执行同步快的场合
在代码进入同步代码快的时候,如果发现对象锁是无锁状态,在当前线程的栈帧中创建一个lock Record的空间,存储对象Mark Word的拷贝,JVM使用CAS操作将对象Mark Word更新为指向Lock Record的引用,如果成功,该线程拥有了这样的对象锁,对象Mark Word的锁标志位设置为00,表明该对象处于轻量级锁的状态;如果失败,锁竞争更加激烈,轻量级锁会升级为重量级锁

补充:轻量级锁抢锁失败,JVM会使用自旋锁,不断尝试获取锁,jdk1.7默认启用

重量级锁
重量级锁使用会有操作系统的互斥量(MUTEX)和条件变量(Condition variable)与其关联,在获取锁的过程修改操作系统层面的两个变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值