阻塞队列与Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是由同一方设置和释放信号量。
ArrayBlockingQueue
只有put方法和take方法才具有阻塞功能
用3个空间的队列来演示阻塞队列的功能和效果。
用两个具有1个空间的队列来实现同步通知的功能。
1 | package java_thread; |
阻塞队列与Semaphore有些相似,但也不同,阻塞队列是一方存放数据,另一方释放数据,Semaphore通常则是由同一方设置和释放信号量。
ArrayBlockingQueue
只有put方法和take方法才具有阻塞功能
用3个空间的队列来演示阻塞队列的功能和效果。
用两个具有1个空间的队列来实现同步通知的功能。
1 | package java_thread; |
堆排序
1 | package sort; |
线程池的概念与Executors类的应用
** 1.创建固定大小的线程池**
1 | package java_thread; |
** 2.创建缓存线程池**
1 | ExecutorService threadPool = Executors.newCachedThreadPool(); |
** 3.创建单一线程池**
1 | ExecutorService threadPool = Executors.newSingleThreadExecutor(); |
**关闭线程池 **
shutdown与shutdownNow的比较
1 | threadPool.shutdownNow(); |
多个线程访问共享对象和数据的方式
1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做。
1 | package java_thread; |
2.如果每个线程执行的代码不同,这时候需要用不同的Runnable对象,有如下两种方式来实现这些Runnable对象之间的数据共享:
方法1:将共享数据封装在另外一个对象中,然后将这个对象逐一传递给各个Runnable对象。每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据进行的各个操作的互斥和通信。
1 | package java_thread; |
方法2:将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类,以便实现对共享数据进行的各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。
1 | package java_thread; |
上面两种方式的组合:将共享数据封装在另外一个对象中,每个线程对共享数据的操作方法也分配到那个对象身上去完成,对象作为这个外部类中的成员变量或方法中的局部变量,每个线程的Runnable对象作为外部类中的成员内部类或局部内部类。
总之,要同步互斥的几段代码最好是分别放在几个独立的方法中,这些方法再放在同一个类中,这样比较容易实现它们之间的同步互斥和通信。
转自 SiteMesh的使用
SiteMesh的介绍就不多说了,主要是用来统一页面风格,减少重复编码的。
它定义了一个过滤器,然后把页面都加上统一的头部和底部。
需要先在WEB-INF/lib下引入sitemesh的jar包:http://wiki.sitemesh.org/display/sitemesh/Download 。这里使用2.4版本。
过滤器定义:
在web.xml中
1 | <filter> |
decorators.xml文件:
WEB-INF下新建decorators.xml文件:
1 | <?xml version="1.0" encoding="utf-8"?> |
安装clickhouse
或者使用docker
参考:https://hub.docker.com/r/clickhouse/clickhouse-server
1 | docker run -d -p 18123:8123 -p 19000:9000 --name some-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server:23.8 |
使用datagrip连接
创建表和测试数据
1 | CREATE TABLE default.my_first_table |
golang客户端连接clickhouse,可以使用 clickhouse-go 这个库
当使用S3作为Amazon EMR的存储的时候,当写入的流量比较大的时候,有时会遇到性能瓶颈,报错如下
1 | Caused by: com.amazonaws.services.s3.model.AmazonS3Exception: Please reduce your request rate. |
在如下的AWS文章中介绍,S3的性能不是按照bucket定义的,而是按照bucket的prefix,对于每个prefix,3500的PUT/COPY/POST/DELETE能力和5000的GET/HEAD能力,如果超过这个限制的话,就会被限流
关于prefix定义,参考文档:aws s3原理和常用命令
参考:从 Amazon EMR 和 AWS Glue 访问 Amazon S3 中数据的性能优化最佳实践
在咨询了AWS的工程师后,说上面的文档不是很准确,更具体的回答是:
1.对于一个刚创建的bucket,默认每个bucket有3500写+5000读的能力
2.当S3 bucket的流量增加后,S3会对应进行bucket的split partition,根据的规则是按照prefix逐位向后分割
意思是对于S3://bucket_name/[a-z,0-9][a-z,0-9]…./object的s3存储结构,prefix的第1个字符有a-z+0-9(26+10=36)种可能性,如果这36个字符出现的可能性是一样的话,则当整个bucket的流量很大的时候,bucket就会扩容到36个partition,从而获得36*(3500/5000)的能力
1.实现文件上传首先需要导入Apache的包,commons-fileupload-1.2.2.jar和commons-io-2.1.jar
实现上传就在add.jsp文件中修改表单
1 | enctype="multipart/form-data" |
完整的add.jsp文件
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
2.在user-servlet.xml中配置上传文件
1 | <!-- 配置上传文件CommonsMultipartResolver --> |
3.在控制器中修改add()方法
1 | //在具体添加用户的时候,是POST请求,就访问以下代码 |
还需要在resources文件夹下面添加upload文件夹
1.搭建环境的第一步是导包,把下面这些包都导入工程中
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/aop
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/apache-commons-logging
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/apache-log4j
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/bean-validator
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/dbcp
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/hibernate-3.6.8.
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/JSTL
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/mysql
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/pager
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/sitemesh
/media/common/工作/Ubuntu软件/SpringMVC_jar包整理/spring
手动导包也可以,不过不是很方便,推荐学习使用maven的pom.xml文件来导入jar包
整个系统的结构
表示层(JSP页面),一般包名是view
** ▼**
控制层,一般包名是action或者web,控制层也会操作实体层
** ▼**
业务逻辑层,一般包名是service
** ▼**
数据持久层,一般包名是dao
** ▼**
实体层(JavaBean),一般包名是model或者entity
写成的过程和上面的方向相反,从下往上写
实体Entity层
** 1.先写User类**
** Id,username,nickname,password,email**
** 其中还包括注入**
** 2.再写Page类**
** public class Pager
** List
** 3.写SystemContext类**
** 7.写UserException异常类**
数据持久层dao层,主要是操作Hibernate,还要写beans.xml
** 4.写IUserDao接口**
** 增、更新、删除、根据ID查用户load、查所用用户List
** 5.实现IUserDao接口**
** 分页find()中取得SystemContext类**
业务逻辑层service层,主要是写验证
** 6.写IUserService接口**
** 增、更新、删除、根据ID查用户load、查所用用户List
** 8.实现IUserService接口**
密码登录验证login、添加用户、修改用户、删除用户、查询用户、列出所有用户、分页find()
控制层action层
9.LoginFilter.java登录权限,实现Filter接口,doFilter()方法
** 在请求是/user/的时候拦截验证权限,没有权限重定向/login,有权限放行*
10.SystemContext.java分页过滤,实现Filter接口,doFilter()方法
** 在请求是/中,如果参数为Pager.offset的时候,拦截取得offset,设置SystemContext中的offset和size*
11.IndexController.java,Session共享数据
在请求是/login的时候,将ModelMap中的属性放入Session中,实现多窗口共享数据
12.UserController.java,总的请求为/user,这也就是MVC模型中的RequestMapping
在请求是/user和/的时候,向model模型中添加——userService.find()
在请求是/add的时候(分GET和POST),向model模型中添加——new User()
在请求是/{id}的时候,向model模型中添加——userService.load(id)
在请求是/{id}/update的时候**(分GET和POST)**…
在请求是/{id}/delete的时候…
最后再传给DispatchServlet,使用model从Controller给视图传值
在jsp中通过 ${ } 取得属性
记得加上@Controller,通过Annotation来配置控制器
注意:在持久层、业务层、控制层中,分别采用@Repository、@Service、@Controller对分层中的类进行注释
1.在user-servlet.xml中加入以下代码,才能使得对静态文件的请求不被Controller捕获,而映射到一个固定的地址
1 | <!-- 将静态文件指定到某个特殊的文件夹中统一处理 --> |
2.在WebContent文件下面,添加resources文件夹和css/main.css文件
** mian.css文件,文字的大小和颜色**
1 | *{ |
3.在list.jsp文件中,加入css样式
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |