Java并发(面试篇)

一、java包:JUC

Java并发(面试篇)_第1张图片

二、

1. 线程创建

(1)继承Thread类

(2)实现Runable接口

(3)创建Callable接口的实现类A,实现call();创建A的实例,使用FutureTask类或者Future接口包装Callable对象,得到对象b,把b作为Thread对象的target创建并启动线程;可以调用FutureTask对象的get()获得子线程执行后的返回值。

FuturnTask与Future的区别

方式三优点:可以获得线程执行后的结果

2. 线程池的种类(参考)

Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程池,而 只是一个执行线程的工具。真正的线程池接口是ExecutorService。 

(1)newCachedThreadPool 

创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制。

(2)newFixedThreadPool 

创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程。

(3)newScheduledThreadPool  

创建一个固定长度的线程池,它可安排在给定延迟后运行命令或者定期地执行。

(4)newSingleThreadExecutor 

这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行。

3. 线程的生命周期

新建(New)【new创建后】、

就绪(Runnable)【start()之后】、

运行(Running)【就绪线程获得cpu,执行run()】、

阻塞 (Blocked)【1.wait(),进入等待队列 2. 同步锁被别线程占用,进入锁池(lock pool)3. sleep()/join()/发出IO请求,当前条件满足才转为运行状态】

和死亡(Dead)【1.正常结束  2. 抛出未捕获Exception或Error 3.调用stop(),容易死锁】5种状态

注:sleep()是static方法,当同步块中调用,锁不会释放。wait()可以释放,且可以通过nofity()唤醒

Java并发(面试篇)_第2张图片

yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。

join 方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执 行结束后,再继续执行当前线程。

Java并发(面试篇)_第3张图片

4. 守护线程

优先级低,为用户线程提供服务,在start()之前可通过SetDaemon(true)设置守护线程,守护线程中产生的新线程也是守护线程,其生命周期依赖于系统,不依赖终端

5. 线程中断

(1)使用退出标志,使线程正常退出,也就是当 run 方法完成 后线程终止。

(2)通过 return 退出 run 方法

(3)通过对有些状态中断抛异常退出 thread.interrupt() 中断。

(4)使用 stop 方法强行终止线程(过期) 

6. 锁
锁分类

可重入锁

synchronize同步锁

7. 锁优化

  • 减少锁持有时间
  • 减少锁粒度

锁分离   常见的锁分离就是读写锁ReadWriteLock。比如 LinkedBlockingQueue 从头部取出,从尾部放数据。

锁消除   锁消除是在编译器级别的事情。在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作,多数是因为程序员编码不规范引起。  

8. 线程上下文切换

上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行切换,上下 文切换过程中的信息是保存在进程控制块(PCB, process control block)中的。PCB还经常被称 作“切换桢”(switchframe)。信息会一直保存到CPU的内存中,直到他们被再次使用。 

Java并发(面试篇)_第4张图片

1. 挂起一个进程,将这个进程在 CPU 中的状态(上下文)存储于内存中的某处。

2. 在内存中检索下一个进程的上下文并将其在 CPU 的寄存器中恢复。

3. 跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行),以恢复该进程在程序中。

 9.线程池

10. volatile 关键字的作用

11. Synchronize

 

你可能感兴趣的:(笔记)