果然目前水平来看,Java才是我的正道
VO对应于页面上需要显示的数据(表单),DO对应于数据库中存储的数据(数据表),DTO对应于除二者之外需要进行传递的数据。
java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.ConcurrentLinkedQueue
ConcurrentHashMap从JDK1.5开始随java.util.concurrent包一起引入JDK中,主要为了解决HashMap线程不安全和Hashtable效率不高的问题。
ConcurrentHashMap在8中 CHM 摒弃了 Segment(锁段)的概念,而是启用了一种全新的方式实现,利用CAS算法。JDK1.8 数组+链表+红黑树数据结构和CAS原子操作实现
CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包中的很多类都使用了CAS技术。
CAS
在多线程高并发编程的时候,最关键的问题就是保证临界区的对象的安全访问。通常是用加锁来处理,其实加锁本质上是将并发转变为串行来实现的,势必会影响吞吐量。而且线程的数量是有限的,依赖于操作系统,而且线程的创建和销毁带来的性能损耗是不可以忽略掉的。虽然现在基本都是用线程池来尽可能的降低不断创建线程带来的性能损耗。
对于并发控制而言,锁是一种悲观策略,会阻塞线程执行。而无锁是一种乐观策略,它会假设对资源的访问时没有冲突的,既然没有冲突就不需要等待,线程不需要阻塞。那多个线程共同访问临界区的资源怎么办呢,无锁的策略采用一种比较交换技术CAS(compare and swap)来鉴别线程冲突,一旦检测到冲突,就充实当前操作指导没有冲突为止。
与锁相比,CAS会使得程序设计比较负责,但是由于其优越的性能优势,以及天生免疫死锁(根本就没有锁,当然就不会有线程一直阻塞了),更为重要的是,使用无锁的方式没有所竞争带来的开销,也没有线程间频繁调度带来的开销,他比基于锁的方式有更优越的性能,所以在目前被广泛应用,我们在程序设计时也可以适当的使用.
不过由于CAS编码确实稍微复杂,而且jdk作者本身也不希望你直接使用unsafe(后面会讲到)来进行代码的编写,所以如果不能深刻理解CAS以及unsafe还是要慎用,使用一些别人已经实现好的无锁类或者框架就好了。
volatile
上面说到当前线程可以发现其他线程对临界区数据的修改,这点可以使用volatile
进行保证。volatile
实现了JMM中的可见性。使得对临界区资源的修改可以马上被其他线程看到,它是通过添加内存屏障实现的。具体实现原理请自行搜索**volatile
**
MySQL的坑:
MySQL 的“utf8mb4”是真正的“UTF-8”。
MySQL 的“utf8”是一种“专属的编码”,它能够编码的 Unicode 字符并不多。
5.5.3以上,更改方法
# For each database: ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; # For each table: ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # For each column: ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # (Don’t blindly copy-paste this! The exact statement depends on the column type, maximum length, and other properties. The above line is just an example for a `VARCHAR` column.)
ACID Atomicity Consistency Isolation Durability
CAP Consistency Availability Partition tolerance
Springmvc的工作流程
-
User向服务器发送request,前端控制Servelt DispatcherServlet捕获;
-
DispatcherServlet对请求URL进行解析,调用HandlerMapping获得该Handler配置的所有相关的对象,最后以HandlerExecutionChain对象的形式返回.
-
DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter.
-
提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)
-
Handler执行完成后,返回一个ModelAndView对象到DispatcherServlet
-
根据返回的ModelAndView,选择一个适合的ViewResolver
-
ViewResolver 结合Model和View,来渲染视图
-
将渲染结果返回给客户端。
volatile:保证可见性,禁止指令重排序优化,但不保证原子性。
1)当一个变量定义为volatile时,它保证了此变量对所有线程可见。当在读取volatile变量时,会进行load操作(从主内存读取,放入工作内存变量中)。当=对volatile变量执行写操作时,会在写入后,进行store操作(把工作内存变量更新到主内存)。所以volatile具有可见性。
2)但是,volatile不保证原子性。
作者:Jay_Wei
链接:https://www.jianshu.com/p/3c1691aed1a5
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
synchronized:保证原子性,可见性,有序性(指令重排)
基于Java内存模型, synchronized执行流程:
(1)线程获得获得互斥锁
(2)清空工作内存
(3)在主内存中拷贝最新变量的副本到工作内存
(4)执行完代码
(5)将更改后的共享变量的值刷新到内存
(6)释放互斥锁
synchronized一般有两种使用方式,同步方法和同步代码块。Java虚拟机基于进入和退出Monitor对象来实现synchronized代码块同步和方法同步,但二者在字节码层面的表现略有差别。
1. synchronized同步块:JVM采用monitorenter、monitorexit两个指令来实现同步。
2.synchronized方法:对于同步方法,JVM采用ACC_SYNCHRONIZED标记符来实现同步
即synchronized通过加锁保证了原子性,可见性,有序性。