该项目采用技术jsp、servlet、jdbc、以及前端框架jQuery,tomcat服务器、mysql数据库 开发工具eclipse,项目属于MVC模式,含有源码、论文、配套开发软件、软件安装教程、项目发布教程。

文件:url80.ctfile.com/f/25127180-740791453-acc5a8?p=551685 (访问密码: 551685)


然后下面的bean文件,里面存放我们封装的实体类,基本上每一个实体类对应着数据库中的一张表,属性就是数据库中的字段

config文件,里面是我们的配置文件,jdbc.properties是对数据库连接的配置,mybatis-config.xml是对mapper.xml文件进行扫描的配置, spring.xml主要是配置组件扫描器,加载外部的properties配置文件,配置数据库连接池等等,springmvc里面是对视图解析器的配置,

controller文件是控制层,导入service层,因为service中的方法是我们使用到的,controller通过接收前端传过来的参数进行业务操作,在返回一个指定的路径或者数据表。比如bookcontroller里面就是对书籍进行增删改查的一下方法

filter这个文件夹下的AdminFilter,他主要是一个拦截的功能。当用户登录以后会把用户信息存入session里,当路径中包含admin,会取出session进行判断,如果session为空,那么证明用户没有登陆过那么就拒绝访问并且跳到首页,如果session不为空并且权限是管理员权限,那么就可以进行访问

mapper文件就是对数据库进行数据持久化操作,他的方法语句是直接针对数据库操作的,这些方法都是针对数据库的,这些mapper.xml里的sql语句就是针对数据库操作的具体实现.


Java并发情况下总是会遇到各种意向不到的问题,比如下面的代码:

int num = 0;

boolean ready = false;
// 线程1 执行此方法
public void actor1(I_Result r) {
if(ready) {
r.r1 = num + num;
} else {
r.r1 = 1;
}
}
// 线程2 执行此方法
public void actor2(I_Result r) {
num = 2;
ready = true;
}
线程1中如果发现ready=true,那么r1的值等于num + num,否则等于1,然后将结果保存到I_Result对象中
线程2中先修改num=2,然后设置ready=true
那大家觉得I_Result中的r1值可能是多少呢?

r1值等于4, 这个大家都能想到, CPU先执行了线程2,然后执行线程1
r1值等于1,这个也容易理解,CPU先执行了线程1,然后执行线程2
那我如果说r1值有可能等于0,大家可能觉得离谱,不信的话,我们验证下。
压测验证结果
由于并发问题出现的概率比较低,我们可以使用openjdk提供的jcstress框架进行压测,就能够出现各种可能的情况。

jcstress:全名The Java Concurrency Stress tests,是一个实验工具和一套测试工具,用于帮助研究JVM、类库和硬件中并发支持的正确性。详细使用可以参考文章:https://www.cnblogs.com/wwjj4811/p/14310930.html

生成压测工程
mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jcstress -DarchetypeArtifactId=jcstress-java-test-archetype -DarchetypeVersion=0.5 -DgroupId=com.alvin -DartifactId=juc-order -Dversion=1.0

生成的工程代码如下图:

填充测试内容

方法actor1是压测第一个线程干的活,将结果保存到I_Result中。
方法actor2是压测第二个线程干的活
类前面的@Outcome注解用来展示验证结果,特别是id="0"这个是我们感兴趣的结果
运行压测工程
mvn clean install
java -jar target/jcstress.jar
查看运行结果
运行结果如下图所示:

有4000多次出现了0的结果
大部分情况的结果还是1和4
你是不是还是很困惑,其实这就是并发执行的一些坑,我们下面来解释下原因。

原因分析
如果先要出现r1的值等于0,那么有一个可能0+0=0,那么也就是num=0。

你可能想num怎么可能等于0,代码逻辑明明是先设置num=2,然后才修改ready=true, 最后才会走到num+num 的逻辑啊…

在并发的世界里,我们千万不要被固有的思维限制了,那是不是有可能num=2和ready=true的执行顺序发生了变化呢。如果你想到这里,也基本接近真相了。

原因: JAVA中在指令不存在依赖的情况下,会进行顺序的调整,这种现象叫做指令重排序,是 JIT 编译器在运行时的一些优化。这也是为什么出现0的根本原因。

指令重排不会影响单线程执行的结果,但是在多线程的情况下,会有个可能出现问题。

理解指令重排序
前面提到出现问题的原因是因为指令重排序,你可能还是不大理解指令重排序究竟是什么,以及它的作用,那我这边用一个鱼罐头的故事带大家理解下。

我们可以把工人当做CPU,鱼当做指令,工人加工一条鱼需要 50 分钟,如果一条鱼、一条鱼顺序加工,这样是不是比较慢?

没办法得优化下,不然要喝西北风了,发现每个鱼罐头的加工流程有 5 个步骤:

去鳞清洗 10分钟
蒸煮沥水 10分钟
加注汤料 10分钟
杀菌出锅 10分钟
真空封罐 10分钟
每个步骤中也是用到不同的工具,那能否可以并行呢?如下图所示:

我们发现中间用很多步骤是并行做的,大大的提高了效率。但是在并行加工鱼的过程中,就会出现顺序的调整,比如先做第二条的鱼的某个步骤,然后在做第一条鱼的步骤。

现代 CPU 支持多级指令流水线,几乎所有的冯•诺伊曼型计算机的 CPU,其工作都可以分为 5 个阶段:取指令、指令译码、执行指令、访存取数和结果写回,可以称之为五级指令流水线。CPU 可以在一个时钟周期内,同时运行五条指令的不同阶段(每个线程不同的阶段),本质上流水线技术并不能缩短单条指令的执行时间,但变相地提高了指令地吞吐率。

处理器在进行重排序时,必须要考虑指令之间的数据依赖性

单线程环境也存在指令重排,由于存在依赖性,最终执行结果和代码顺序的结果一致
多线程环境中线程交替执行,由于编译器优化重排,会获取其他线程处在不同阶段的指令同时执行
volatile关键字
那么对于上面的问题,如何解决呢?

使用volatile关键字。

volatile 的底层实现原理是内存屏障,Memory Barrier(Memory Fence)

对 volatile 变量的写指令后会加入写屏障
对 volatile 变量的读指令前会加入读屏障
内存屏障本质上是一个CPU指令,形象点理解就是一个栅栏,拦在那里,无法跨越。

内存屏障分为写屏障和读屏障,有什么有呢?

保证可见性
写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中
读屏障保证在该屏障之后,对共享变量的读取,加载的是主存中最新数据
保证有序性
写屏障会确保指令重排序时,不会将写屏障之前的代码排在写屏障之后
读屏障会确保指令重排序时,不会将读屏障之后的代码排在读屏障之前

回到前面的问题,如果对ready加了volatile以后,那么num=2就无法到后面去了,同样读取也是,如上图所示。

final底层也是通过内存屏障实现的,它与volatile一样。

对final变量的写指令加入写屏障。也就是类初始化的赋值的时候会加上写屏障。
对final变量的读指令加入读屏障。加载内存中final变量的最新值。
总结
JAVA并发中的有序性问题其实比较难理解,本文通过一个例子验证了并发情况下会出现有序性的问题,从而引发意想不到的结果。这个主要的原因是为了提高性能,指令会发生重排序导致的。为了解决这样的问题,我们可以使用volatile这个关键字修饰变量,它能够保证有序性和可见性,但是无法保证原子性。如果以后遇到一些成员变量或者静态变量就要特别注意了,需要分析并发情况下会有哪些问题。

JavaWeb大作业-网上书城(源码+文档+数据库+答辩)相关推荐

  1. 基于SSM的物料管理系统(源码+文档+数据库)

    目录 摘要 一.需求分析 二.文档目录 三.功能性需求分析 四.非功能性需求分析 五.项目数据库设计 六.主要功能模块实现 6.1 登录板块 6.1.1 后台登录核心验证代码 6.1.2 前台登录跳转 ...

  2. 【毕设课设】【毕设课设】JAVA web健身房管理系统(源码+文档+数据库)

    1) 数据库说明 (1)本系统使用数据库为MySql5.5.40,使用时向数据库导入文件gym-mysql.sql. (2)可登陆的 管理员登录账号:20190001,密码为:123123; 2) 程 ...

  3. 基于微信小程序学校部门年终绩效考核自动评分系统(源码+文档+数据库+PPT)

    基于微信小程序的部门年终绩效考核系统,为加强学校运营队伍建设提高学校管理力,合理评价教师及部门年度工作计划完成情况,促进整体绩效改进,鼓励管理团队注重对下属进行帮助.提升,促进团队扩张和发展,特制定本 ...

  4. SpringBoot网上书城的设计与实现源码+文档

     博主介绍:✌在职Java研发工程师.专注于程序设计.源码分享.技术交流.专注于Java技术领域和毕业设计✌ 项目名称 SSM框架特产销售网站设计与开发源码 视频效果 SpringBoot网上书城的设 ...

  5. java计算机毕业设计网上花店源码+系统+mysql数据库+LW文档+部署文件

    java计算机毕业设计网上花店源码+系统+mysql数据库+LW文档+部署文件 java计算机毕业设计网上花店源码+系统+mysql数据库+LW文档+部署文件 本源码技术栈: 项目架构:B/S架构 开 ...

  6. 计算机毕业设计Javaweb实验室课表管理系统(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Javaweb实验室课表管理系统(源码+系统+mysql数据库+lw文档) 计算机毕业设计Javaweb实验室课表管理系统(源码+系统+mysql数据库+lw文档) 本源码技术栈: 项目 ...

  7. java计算机毕业设计在线作业提交系统源码+系统+mysql数据库+lw文档

    java计算机毕业设计在线作业提交系统源码+系统+mysql数据库+lw文档 java计算机毕业设计在线作业提交系统源码+系统+mysql数据库+lw文档 本源码技术栈: 项目架构:B/S架构 开发语 ...

  8. 计算机毕业设计Java作业批改管理系统(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Java作业批改管理系统(源码+系统+mysql数据库+lw文档) 计算机毕业设计Java作业批改管理系统(源码+系统+mysql数据库+lw文档) 本源码技术栈: 项目架构:B/S架构 ...

  9. 计算机毕业设计Javaweb扶贫产品物资管理平台(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Javaweb扶贫产品物资管理平台(源码+系统+mysql数据库+lw文档) 计算机毕业设计Javaweb扶贫产品物资管理平台(源码+系统+mysql数据库+lw文档) 本源码技术栈: ...

最新文章

  1. python数据库编程 代码 源码_Python可以这样学_Python教程
  2. Tensorflow【实战Google深度学习框架】—使用 TensorFlow 实现模型
  3. mysql查看执行计划_如何查看MySQL的执行计划
  4. SAP Fiori My note应用的add to功能的后台ABAP实现
  5. 【PHP学习】—get请求传递参数(五)
  6. 设计模式(2) 生成器模式(BUILDER)
  7. (13) IFC格式说明 (Industry Foundation Class)
  8. 若依管理系统漏洞利用
  9. c++判断整数翻转溢出_C++整数溢出
  10. *.LDB文件介绍(转)
  11. 前端学习第三站——Vue2基础篇
  12. VBS调用ping检测ip连通情况
  13. css创意立体字特性
  14. 如何删除MacOS自带的输入法的自造词(Catalina)
  15. MySQL数据库冰人集团
  16. Alibaba大牛常读的10本Java实战书籍,(Java开发进阶必备书单),可以白嫖了
  17. 二元关系——离散数学part 1
  18. 微信小程序简单实现上拉触底onReachBottom数据分页请求
  19. 为什么手机充电时会感觉麻麻的,有问题吗?
  20. 基于springboot的药店进销存管理系统#毕业设计

热门文章

  1. vue3 watch的用法
  2. android4版本的手机有,Android版本份额:还有两成人用安卓4.4
  3. 【Unity】百度翻译API接口实时翻译功能
  4. _kgl_large_heap_warning_threshold参数引起的问题
  5. SLS-日志服务分析查询
  6. 荣耀猎人游戏本什么时候发布 荣耀猎人游戏本配置曝光
  7. 基于C++的定时关机程序
  8. 手机文件夹是英文不敢随便删?只要找出这四个文件夹,16G不输32G
  9. JQuery点击事件添加间隔
  10. Fiddler Everywhere调试代理来扩大您的调试工作