Java架构师必备知识点(高级程序员教程必备)

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java架构师必备知识点(高级程序员教程)

2019年3月

一、并发编程

1.线程安全:

当多个线程访问某一个类(对象)时这个类始终都能表现出正确的行为,那么这个类(对象和方法)就是线程安全的。

2.synchronized:

可以在任意对象以及方法上加锁,而加锁的这段代码称为"互斥区"或者"临界区"。

一个线程想要执行synchronized修饰的方法里的内容,首先是尝试获得锁,如果拿到锁,执行synchronized方法体里面的内容

如果拿不到那么这个线程会不断的尝试获得这把锁,直到拿到为止,而且是多个线程去竞争这把锁。

3.多个线程多个锁:

多个线程,每个线程都将可以拿到自己指定的锁,分别获得锁之后,执行synchronized方法体的内容,

关键字synchronized获得的锁都是对象锁,而不是把一段代码(方法)当做锁,在静态方法上机上synchronized获得的锁为类级别的锁,表示锁定类。

4.对象锁的同步和异步:

同步synchronized:同步就是共享,同步的目的是为了线程安全,对于线程安全需要满足两个特性:原子性(同步)、可见性。

异步asynchronized:异步就是独立,相互之间不受任何制约。

5.脏读:

对于对象的同步和异步方法,我们在设计程序的时候,一定要考虑问题的整体,不然就会出现数据不一致错误,很经典的错误就是脏读(dityread)。

在我们对一个对象的方法加锁的时候,需要考虑业务的整体性,即为setValue和getValue方法同时加锁synchronized同步关键字

保证(service)业务逻辑层的原子性,不然会出现业务逻辑错误。

6.synchronized锁重入:

关键字synchronized拥有重入锁的功能,也就是在使用synchronized时,当一个线程得到一个对象的锁后,再次请求此对象时是可以再次得到该对象的锁。

7.出现异常,锁自动释放:

对于web应用程序,异常释放锁的情况,如果不及时处理,很可能对应用程序业务逻辑产生严重的错误。

比如:现在执行一个队列任务,很多对象都去在等待一个对象正确执行完毕再释放锁,

但是一个对象出现由于异常的出现,导致业务逻辑没有正常执行完毕,就是释放了锁,那么后面的对象执行的都是错误的业务逻辑。

8.synchronized代码块:

使用synchronized声明的方法在某些情况下是有弊端的,比如:A线程方法调用一个时间很长的任务,那么B线程

必须等待很长的时间才能执行,这样的情况下可以使用synchronized代码块去优化代码执行时间,也就是减小锁的时间。

synchronized可以使用任何object对象进行加锁,用法比较灵活,不要使用string的常量加锁,会出现死循环问题。

9.锁对象改变的问题:

当使用一个对象进行加锁的时候,要注意对象本身发生改变的时候,那

么持有的锁就不同,如果对象不发生改变,那么依然是同步的,即使是对象的属性发生了改变。

10.volatile关键字:

volatile的作用主要是使变量在多个线程间可见,在java中每一个线程都有一块工作内存区,其中存放着所有线程共享的变量值的拷贝,

当线程执行时,在自己的工作内存区中操作这些变量,为了存取一个共享的变量,一个线程通常先获取锁定并去清除它的工作内存区,

把这些共享变量从所有线程的共享内存区中正确的装入到他所在的工作内存区中,当线程解锁时保证该工作内存区中变量的值写回到共享内存中。

一个线程可以执行的操作有:使用(use)、赋值(assign)、装载(load)、存储(store)、锁定(lock)、解锁(unlock)。

主线程可以执行的操作有:读(read)、写(write)、锁定(lock)、解锁(unlock),每个操作都是原子的。

volatile的作用是强制线程到主内存(共享内存)里去读取变量,而不去工作内存区读取,从而实现了多个线程间变量可见,

也就是满足线程安全的可见性。

11.volatile关键字的非原子性:

volatile关键字虽然有多个线程间的可见性,但不具备同步性(原子性),可以算的上是一个轻量级的synchronized,

性能比synchronized强很多,不会造成阻塞,volatile只针对于多个线程可见的变量操作,并不能代替synchronized的同步功能。

如要实现原子性使用atomic类的系列对象,支持原子性操作,atomic只支持本身方法原子性,并不保证多个线程的原子性。

12.多线程通信wait和notify:

线程是操作系统中独立的个体,但这些个体不经过处理就不能成为一个整体,线程间的通信就成为整体的比用方法之一,

当线程存在线程指挥,系统间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对线程任务在处理的过程中进行有效的把控和监督。

使用wait和notify方法实现线程间的通信,这两个方法都是object类的方法,java为所有的类都提供了这两个方法,wait和notify都

必须配合synchronized关键字使用,wait方法释放锁,notify不释放锁。

13.使用wait和notify模拟queue:

blockingqueue:它是一个队列,并且支持一个阻塞的机制,阻塞的放入和得到数据,要实现linkedblockingqueue的方法是put()和take(),

put(anobject):把anObject放入blockingqueue,如果blockingqueue没有空间,则调用此方法的线程被阻断,直到blockingqueue里面有空间再继续。

take:取走blockingqueue里排在首位的对象,如果blockingqueue为空,阻断进入等待状态,直到blockingqueue里有新的方法加入。

14.ThreadLocal:

线程局部变量,是一种并发访问变量的解决方案,与其synchronized等加锁的方式不同,ThreadLocal完全不提供锁,而使用空间换时间的手段,为每个线程提供变量的独立副本,以保证线程安全。从性能上说,不具有绝对的优势,在并发不是很高的时候加锁的性能会更好,

但作为一套完全与锁无关的线程安全解决方案,在高并发量或者激烈的场景,用ThreadLocal可以在一定程度上减少锁的竞争。

15.单例和多线程:

单例模式最常见的是饿汉模式和懒汉模式,一个直接实例化对象,一个在调用方法时进行实例化对象,在多线程的模式中,考虑到性能和线程安全问题,一般选择最近经典的两种单例模式,在性能提高的同时,又保证了线程安全。

17.同步类容器:

相关文档
最新文档