java面试总结--设计模式及多线程

一.常用的设计模式有哪些

  1. 单例模式
  2. 装饰模式:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
  3. 工厂模式:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
  4. 代理模式:比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
  5. 适配器模式:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

二、多线程

1.Thread和Runnable的区别?

1)可以避免由于Java的单继承特性带来的局限。

2)实现资源共享。

2.多线程有哪些状态?

创建、运行、阻塞、终止。

3)yield和join区别

yield方法暂停当前正在执行的线程对象。调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。【并不能保证一定会这样,很少使用,一般调试和测试使用。】

join方法等待该线程终止。等待调用join方法的线程结束,再继续执行。比如需要主线程等子线程运行结束。

4)wait和sleep区别

wait方法使当前线程进入阻塞状态,如果指定时间,则在这个时间后自动唤醒,如果没有指定时间,则要其他线程使用notify唤醒。和sleep区别为wait方法会释放锁,sleep不同释放同步方法的锁。

3.线程池有哪几种?

4.lock和synchronized区别?

当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized

5.线程锁有哪几种?

ReentrantLock和ReentrantReadWriteLock

ReentrantReadWriteLock:对两个线程如果同时读,不需要锁,会提高效率,写读和写写会加锁。如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。

6.公平锁和非公平锁区别?

公平锁即尽量以请求锁的顺序来获取锁。比如同是有多个线程在等待一个锁,当这个锁被释放时,等待时间最久的线程(最先请求的线程)会获得该所,这种就是公平锁。

非公平锁即无法保证锁的获取是按照请求锁的顺序进行的。这样就可能导致某个或者一些线程永远获取不到锁。

在Java中,synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序。

而对于ReentrantLock和ReentrantReadWriteLock,它默认情况下是非公平锁,但是可以设置为公平锁。

7.乐观锁和悲观锁区别?

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。

  乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

例如git提交代码类似使用乐观锁,只有提交更新时才会去检测是否冲突,如果冲突返回给用户去处理。

猜你喜欢

转载自blog.csdn.net/zht245648124/article/details/90573474
今日推荐