Java 并发编程的相关问题整理

1. 线程与进程.

进程是系统运行程序的基本单位.而线程是进程在执行过程中产生的更小的执行单位.与进程不同的是,不同的是在Java中,线程有自己独立的程序计数器/虚拟机栈/本地方法栈,还可以共享进程的堆和方法区资源.简单来说,就是儿子可以共享老爸的钱和人脉.

以前的Java线程是用户线程,间接通过jvm操作内核线程.现在已经改变了,java线程的本质就是操作系统的线程.一个java线程就对应一个内核线程.

2. 创建线程

1. 继承Thread类,重写run方法.Thread父类的run方法是不执行任何操作并返回,所以子类需要重写.这是唯一的一种方式创建线程---->new Thread().start.,而不hi是new Thread().run

2.实现Runnable接口,并传给Thread构造器.

3.实现Callable,接口,创建有返回值的线程.

4.使用Executor框架创建线程池.

四者的区别:第一种是最原始最根本的,其他方式都是依赖该方式创建线程的.但这个方式有个十分明显的缺点,因为Java无法多继承,所以一旦继承了Thread类,就意味着这个类无法继续继承了.所以一般用Runable方法进行任务创建(该方法没有返回值,并且同个任务的资源可以共享.),Callable方法可以执行后返回值.Executor是由任务/任务的执行/异步计算的结果组成的.

3.线程的生命周期和状态.

谈到生命周期,最起码有三个阶段--->创建/运行/死亡.但多了3种状态,阻塞/等待/超时等待,
wait()方法是Object类的一个方法,他会让当前线程进入等待,并且释放对象上的所有锁.该线程会进入到等待池,等待其他获取该对象锁的线程主动调用notify唤醒方法.sleep()方法属于Thread类,可以在任何地方调用.wait方法需要定义共享资源,并且在同步代码块中使用.两者的区别,在于同步代码块中,使用sleep方法不会让其他线程进入到同步代码块,也就是不会释放对象锁,但是wait方法会.

4.多线程中的并发与并行

并发:同一时间段执行

并发:同一时刻执行

5.死锁

死锁的条件算是必背题了.

1.互斥:一个资源只能给一个线程占用

2.请求和保持条件:请求其他资源遇到阻塞,但不放弃自己已经获得资源.

3.不剥夺条件:线程占用资源,不使用完毕不能被剥夺.

4.循环等待条件:若干线程头尾衔接循环等待.

如何破坏:
2.一次性获取所有资源

3.申请不到就主动放弃已占有的资源

4.按序申请,反序释放.

6.锁与线程

多线程往往会遇到不安全的问题,对于同一份数据的修改访问可能是不一致.这一点和数据库的设计是差不多的.除了死锁外,往往就是数据不安全的问题.对于数据安全访问的手段,主要的手段就是多版本并发控制和加锁.锁的互斥和可见性.Valatile的特性是将线程本地内存在修改后强制刷新到主内存中,同时可以避免指令重排(在单例模式下可以看到)

7.悲观锁和乐观锁

这两种并不是实际意义上的锁/关键字,而是两种不同的思想.乐观锁认为访问资源不会出问题,在事后进行校验就行了.主要是通过版本号控制.所以压根就没有加过锁.多用于写少读多的场景.而悲观锁认为每次获取资源都会被修改,所以每次获取资源都会上锁.适用于写多杜少.乐观锁使用版本号机制/CAS算法.CAS算法简单来说,就是修改完值后,对比下原值有没有变化,变化就不再修改.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值