面试那些事!----------并发编程

为什么要使用并发编程?

        提升多核CPU的利用率:一般来说一台主机上的会有多个CPU核心,我们可以创建多个线程,理论上讲操作系统可以将多个线程分配给不同的CPU去执行,每个CPU执行一个线程,这样就提高了CPU的使用效率,如果使用单线程就只能有一个CPU核心被使用。

简单来说就是:充分利用cpu的计算能力,将业务拆分,提高效率。

凡事都有两面性:多线程好处与坏处。


多线程的缺点:
    并发编程的目的就是为了能提高程序的执行效率,提高程序运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、上下文切换、线程安全、死锁等问题。
    
    线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;

    多线程需要协调和管理,所以需要 CPU 时间跟踪线程;

    线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题。

这里就涉及到了锁啊,线程啊,怎么保证多线程的运行安全,并发编程三个必要因素是什么。

并发编程三要素

三要素
原子性:原子,即一个不可再被分割的颗粒。原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。

可见性:一个线程对共享变量的修改,另一个线程能够立刻看到。(synchronized,volatile)

有序性:程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)

线程的创建

最开始的方法:继承 Thread 类
public class MyThread extends Thread
public void run() 

实现 Runnable 接口
public class MyRunnable implements Runnable
public void run() 

实现 Callable 接口
public class MyCallable implements Callable<Integer>
public Integer call() 

使用匿名内部类方式
在类的里面使用Thread类创建一个出来。

然后说下Runnable 和 callable 有什么区别:
上面可以砍出来都是接口
都可以编写多线程程序
都采用Thread.start()启动线程的。

主要区别:
Runnable 接口 run 方法无返回值;Callable 接口 call 方法有返回值,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。

Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;Callable 接口 call 方法允许抛出异常,可以获取异常信息
注:Callalbe接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。


 

线程的安全与死锁

出现线程安全问题的原因一般都是三个原因:

1)线程切换带来的原子性问题
解决办法:使用多线程之间同步synchronized或使用锁(lock)。

2)缓存导致的可见性问题
解决办法:synchronized、volatile、LOCK,可以解决可见性问题

3)编译优化带来的有序性问题
解决办法:Happens-Before 规则可以解决有序性问题


线程死锁:
形成死锁的四个必要条件
1)互斥条件:在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,就只能等待,直至占有资源的进程用毕释放。

2)占有且等待条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不可抢占条件:别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。

4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。(比如一个进程集合,A在等B,B在等C,C在等A)

什么是死锁
1)死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。

2)多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

怎么解决死锁
1)避免一个线程同时获得多个锁。

2)避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。

3)尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值