Java并发编程

本文详细探讨了并发编程的优点和缺点,涉及原子性、可见性和有序性等核心概念,讲解了如何保证多线程安全,区分了并行与并发,并剖析了线程、进程、上下文切换和守护线程的区别,以及线程死锁的条件与避免策略。此外,还介绍了线程池的工作原理和常见参数设置。
摘要由CSDN通过智能技术生成

1 并发编程的优缺点

        优点:充分利用CPU多核的能力;对业务进行拆分,提高整体性能

        缺点:可能遇到很多问题,如:内存泄漏、上下文切换、死锁、线程安全

2 并发编程三要素

        原子性:一个或多个操作同时成功或同时失败

        可见性:一个线程对共享变量的修改,另一个线程能立刻感知

        有序性:单线程环境下,JVM可能会对指令顺序进行重排序(提高运行效率,最终结果一致),而多线程环境下,一定要避免JVM对指令的重排序

3 如何保证多线程运行的安全性

        导致线程安全的原因及解决办法:

                线程切换引发的原子性问题:sychronized、Lock、Atomic(CAS)

                缓存导致的可见性:sychronized、volatile、Lock

                编译优化带来的有序性问题:volatile(Happends-Before规则)

4 并行和并发的区别

        并发:多个任务在同一CPU核上,按细分的时间片轮流执行

        并行:多个任务在多个CPU核上

        串行:多个任务按顺序执行

5 什么是多线程?多线程的劣势?

        多线程:程序中包含多个执行流,指在程序中可以同时开启多个不同的线程来执行不同的任务

        优点:提高CPU利用率;提高程序效率

        缺点:线程需要占用内存;多线程需要CPU去跟踪调度;资源共享问题

6 线程和进程

        进程:内存中运行的应用程序(jvm .exe QQ...)

        线程:进程的一个执行单元

        区别:

                根本区别:进程是OS资源分配的基本单位;线程是CPU任务调度和执行的基本单位

                资源开销:每个进程有自己独立的代码和数据空间(程序上下文),程序切换有较大的开销;线程≈轻量级进程,同一类线程共享代码和数据空间,每个线程有自己独立的线程栈和程序计数器PC,线程切换开销小

                包含关系:进程包含线程,一个进程中有多个线程,线程执行过程不是一条线,而是多条线共同完成

                内存分配:同一类线程共享当前进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

                影响关系:进程之间是独立的,一个进程崩溃不会导致其它进程崩溃;而一个线程崩溃可能导致整个进程崩溃

7 什么是上下文切换?

        多线程编程中,一般线程个数大于CPU核心个数,而一个CPU在任意时间只能被一个线程使用,为了让这些线程得到有效执行,CPU采用时间片轮转,当一个线程时间用完时应该处于就绪状态,将CPU的使用权交给其它线程,这个过程属于上下文切换(任务从保存到再加载的过程

8 守护线程和用户线程的区别?

        用户线程:运行在前台,执行具体任务(如程序主线程、连网网络的子线程等)

        守护线程:运行在后台,为其它前台线程提供服务;随着用户线程的结束而结束(如GC线程)

9 线程死锁?

        概念:两个或两个线程争夺同一资源且都无法主动释放,而造成的阻塞现象

        死锁的四个必要条件:

                互斥条件:线程/进程对于获取到的资源具有排他性,一个资源仅能被一个线程占用,直到被线程释放

                请求与保持条件:线程如果被阻塞,对已获得的资源不释放

                不剥夺条件:线程已获得的资源在未使用完之前,不被其它线程强行剥夺,只能自己主动释放

                循环等待条件:发生死锁时,所等待的线程之间必定会形成死循环

        如何避免线程死锁:

                破坏互斥条件:无法破坏,锁设计的初衷

                破坏请求与保持条件:一次性申请所有资源

                破坏不剥夺条件:占用部分资源的线程,若申请不到其它资源,主动释放占用的资源

                破坏循环等待条件:分析造成死循环处,改变申请资源顺序

10 创建线程有哪些方式?

        继承Thread类

        实现Runnable接口

        实现Callable接口

        使用Executors工具类创建线程池

        

        Runnable接口和Callable接口有什么区别?

                用法上无区别;Callable接口允许接收返回值,和Future、FutureTask配合使用,future.get()处阻塞

11 线程的start()和run()方法有什么区别?

        run()允许调用多次,存在于主线程,是线程中的一个函数

        start()方法只允许调用一次,Thread类通过调用start()方法来开启一个线程

        new Thread()时,线程进入新建状态,调用start()方法,线程进入就绪状态并等待CPU分配时间片,分配到时间片后进入运行状态,真正调用run()方法实现多线程

12 线程的生命周期和五种状态

阻塞情况:

        等待阻塞:线程执行wait()

        同步阻塞:线程在获取synchronized锁失败

        其它阻塞:调用线程sleep()或join或发出I/O请求

线程调度策略:

        发生如下情况会终止线程执行:

                线程中调用yield(),让出CPU使用权

                线程调用sleep()使线程进入睡眠

                线程由于IO操作受到阻塞(运算靠CPU,IO操作是内存操作)

                另一个高优先级线程出现

                分配给线程的时间片用完

线程同步及调度的方法:

        wait():使线程处于阻塞状态,释放持有对象的锁(用于synchronized中)

        sleep():使正在运行的线程处于睡眠阻塞状态

        notify():唤醒一个处于阻塞状态的线程,JVM随机唤醒

        notifyAll():唤醒所有处于阻塞状态的线程,让其竞争

sleep()和wait()的区别:

        类不同:sleep属于Thread类;wait属于Object类

        是否释放锁:sleep不释放锁;wait释放锁

        用途:sleep用于暂停执行;wait用于线程间通信

        用法:sleep线程会自己醒来;wait必须通过notify/notifyAll唤醒

sleep()和yield()方法有什么区别:

        sleep给其它线程运行机会时不用考虑优先级;yield只会给同优先级/高优先级机会

        线程执行sleep进入阻塞;执行yield进入就绪

interrupted和isInterrupted的区别:(AQS中用于中断线程执行)

        interrupt用于线程中断

        interrupted用于判断中断信号是true还是false,并且清除中断标记

        isInterrupted查看当前中断信号是true还是false;不清除标记

13 监视器Monitor,线程如何同步?

        在java中,每个监视器和一个对象的引用相关联,为了实现监视器的互斥功能,每个对象都关联了一把锁;一旦一个方法或代码块被synchronized修饰,这个部分就会被放入监视器中,监视器确保一次只能由一个线程执行这部分代码

14 线程池流程

 当提交任务时,线程池队列满时:

        如果是无界队列LinkedBlockingQueue,继续添加任务到阻塞队列中执行

        如果是有界队列ArrayBlockingQueue,如果队列满时,判断还能否开辟线程,若不能开辟线程则执行拒绝策略

线程池参数介绍:

        corePoolSize:核心线程数,<=计算机的物理核

        maximumPoolSize:最大线程数,<=计算机的逻辑核

        keepAliveTime:线程不干活的时间(非核心线程,超过不干活的时间后,让OS关闭线程)

        BlockingQueue<Runnable> workQueue:存放未来得及执行的任务

        ThreadFactory:创建线程的工厂

        RejectedExecutorHandler:拒绝策略

线程池状态:

        Running:线程池创建后的状态,允许接收新任务、处理已添加的任务

        ShutDown:不接收新任务,能处理已添加的任务;threadPool.shutDown();

        Stop:不接受新任务,不处理已添加的任务;threadPool.shutDownNow();

        Tidying:所有任务结束后,线程池的状态;ShutDown状态下,且队列任务也为空

        Terminated:线程池处在TIDYING状态时,执行完terminated()之后

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值