自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(25)
  • 资源 (1)
  • 收藏
  • 关注

转载 模板方法模式

《JAVA与模式》之模板方法模式在阎宏博士的《JAVA与模式》一书中开头是这样描述模板方法(Template Method)模式的:  模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

2016-08-30 18:38:02 408

转载 策略模式

《JAVA与模式》之策略模式在阎宏博士的《JAVA与模式》一书中开头是这样描述策略(Strategy)模式的:  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模式的结构  策略模式是对算法的包装,是把使用算法的责任和算法本身分割开

2016-08-30 18:35:30 313

转载 适配器模式

《JAVA与模式》之适配器模式在阎宏博士的《JAVA与模式》一书中开头是这样描述适配器(Adapter)模式的:  适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式的用途  用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极、阴极外,还有一个地极。而有些地方的电源插座却只有两极

2016-08-30 18:34:28 265

转载 装饰模式

《JAVA与模式》之装饰模式在阎宏博士的《JAVA与模式》一书中开头是这样描述装饰(Decorator)模式的:  装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式的结构  装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰

2016-08-30 15:59:47 493

转载 java中的抽象接口

在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现。       今天小菜提到的“抽象接口”,就是用来解决这个问题的。       为了不误导读者,先说明一下,什么是“抽象接口”。       所谓“抽象接口”,即在提供接口的同时,提供

2016-08-25 10:10:36 331

转载 Spring技术内幕——深入解析Spring架构与设计原理(一)IOC实现原理

IOC的基础 下面我们从IOC/AOP开始,它们是Spring平台实现的核心部分;虽然,我们一开始大多只是在这个层面上,做一些配置和外部特性的使用工作,但对这两个核心模块工作原理和运作机制的理解,对深入理解Spring平台,却是至关重要的;因为,它们同时也是Spring其他模块实现的基础。从Spring要做到的目标,也就是从简化Java EE开发的出发点来看,简单的来说,它是通过对PO

2016-08-15 17:08:35 4615

转载 Spring 源码分析(二) —— 核心容器

目录[-]大道新途容器概述设计实现    接口设计    BeanFactory容器的设计    ApplicationContext容器的设计    依赖注入    其他特性闲言小叙    Spring Ioc容器小结    太史公曰大道新途        应用开发中的容器,是指应用代码的运行框架。不基于容器的开发,是杂乱无章的,事实上,很多架构或者应用都是以

2016-08-09 09:41:50 5528 2

转载 Spring学习总结——Spring整合MyBatis(Maven+MySQL)二

目录一、在Web项目中启动Spring容器1.1、使用监听器启动Spring容器1.2、使用Servlet方式启动Spring容器二、获取ApplicationContext实例2.1、使用工具类WebApplicationContextUtils获得Spring容器2.2、实现接口ApplicationContextAware三、基于注解的声明式事务管

2016-08-08 16:17:35 570

转载 Spring学习总结——Spring整合MyBatis(Maven+MySQL)一

目录一、 使用Maven创建一个Web项目二、使用MyBatis完成MySQL数据库访问2.1、添加依赖2.2、准备数据2.3、创建java Bean2.4、创建实例与表的映射文件2.5、创建MyBatisCfg.xml文件 2.6、实现数据访问功能2.7、测试运行2.8、整合log4j2三、使用Spring4.X整合MyBatis3.X初级版3.1、修改p

2016-08-08 16:16:32 1578

转载 Spring学习总结——Spring实现AOP的多种方式

目录一、基于XML配置的Spring AOP二、使用注解配置AOP三、AspectJ切点函数四、AspectJ通知注解五、零配置实现Spring IoC与AOP六、示例下载AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术。AOP是OOP的补充,是Spring框架中的一个

2016-08-08 16:13:26 40961 12

转载 Spring学习总结——Spring实现IoC的多种方式

目录一、使用XML配置的方式实现IOC二、使用Spring注解配置IOC三、自动装配四、零配置实现IOC五、示例下载控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中我们使用面向对象编程对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序

2016-08-08 16:10:36 4463

转载 Spring MVC 深入及对注解的详细讲解

核心原理1.       用户发送请求给服务器。url:user.do2.       服务器收到请求。发现Dispatchservlet可以处理。于是调用DispatchServlet。3.      DispatchServlet内部,通过HandleMapping检查这个url有没有对应的Controller。如果有,则调用Controller。4、    Con

2016-08-08 16:05:26 3365

转载 Spring注解原理的详细剖析与实现

一、注解的基本概念和原理及其简单实用注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解来使用这些数据),用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。其实就是更加直观更加明了的说明,这些说明信息与程序业务逻辑没有关系,并且是供指定的工具或框架使用的。A

2016-08-08 16:02:48 40037 11

转载 java原理—反射机制

一、什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提 出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中 LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到

2016-08-08 11:31:29 467

转载 java反射机制—— 利用反射机制实例化对象

一、Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(度娘文库是这么说的)二、这篇文章主要介绍一下通过

2016-08-08 11:30:44 4948

转载 Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解

目录一、控制器定义1.1、实现接口Controller定义控制器1.2、使用注解@Controller定义控制器 二、@RequestMapping详解2.1、value 属性指定映射路径或URL模板2.1.1、指定具体路径字符2.1.2、路径变量占位,URI模板模式2.1.3、正则表达式模式的URI模板2.1.4、矩阵变量@MatrixVariab

2016-08-05 16:50:44 4685

转载 Spring MVC 学习总结(一)——MVC概要与环境配置

目录一、MVC概要二、Spring MVC介绍三、第一个Spring MVC 项目:Hello World3.1、通过Maven新建一个Web项目3.2、添加依赖的jar包3.3、修改web.xml注册中心控制器DispatcherServlet3.4、添加Spring MVC配置文件3.5、创建HelloWorld控制器3.6、创建视图3.7、测试运行3.8、示例下载

2016-08-05 10:55:03 886

转载 《深入理解mybatis原理》 Mybatis数据源与连接池

对于ORM框架而言,数据源的组织是一个非常重要的一部分,这直接影响到框架的性能问题。本文将通过对MyBatis框架的数据源结构进行详尽的分析,并且深入解析MyBatis的连接池。    本文首先会讲述MyBatis的数据源的分类,然后会介绍数据源是如何加载和使用的。紧接着将分类介绍UNPOOLED、POOLED和JNDI类型的数据源组织;期间我们会重点讲解POOLED类型的数据源和其实

2016-08-03 09:26:32 574

转载 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理

MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能。本文将全面分析MyBatis的二级缓存的设计原理。1.MyBatis的缓存机制整体设计以及二级缓存的工作模式 如上图所示,当开一个会话时,一个 SqlSession 对象会使用一个Executor 对象来完成会话操作, MyBatis的二级缓存机制的关键就是对这个

2016-08-03 09:17:58 305

转载 《深入理解mybatis原理》 MyBatis事务管理机制

MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面。本文将讲述MyBatis的事务管理的实现机制。首先介绍MyBatis的事务Transaction的接口设计以及其不同实现JdbcTransaction 和 ManagedTransaction ;接着,从MyBatis的XML配置文件入手,讲解MyBatis事务工厂的创建和维护,进而阐述了MyBati

2016-08-03 09:16:09 1011

原创 mybatis-config配置setting说明

1.       配置设置 –>  2.             3.               配置全局性 cache 的 ( 开 / 关) default:true –>  4.                name=“cacheEnabled” value=“true”/>  5.                 6.               是否使用 懒

2016-08-02 16:44:09 9528

转载 使用Maven自动部署插件

Java程序员常常有这样的困惑,每天开发项目的时候都要重复着“写代码 -> 打包 -> 停止服务 -> 部署代码 -> 启动服务 -> 测试”。尤其是当项目的历史比较长,目录结构比较混乱的时候更是如此。这其中有很多时间都花在了手动启停服务,部署包上面了。今天就说说怎样使用Maven的插件来实现自动“打包 -> 停止服务 -> 部署代码 -> 启动服务”。修改Maven的配置文件po

2016-08-02 11:30:23 278

转载 eclipse构建maven的web项目

使用Eclipse的maven构建一个web项目1、选择建立Maven Project 选择File -> New -> Other,在New窗口中选择 Maven -> Maven Project;点击next        2、选择项目路径 Usedefault Workspace location默认工作空间        3、选择

2016-08-02 11:05:01 195

转载 使用RunWith注解改变JUnit的默认执行类,并实现自已的Listener

使用RunWith注解改变JUnit的默认执行类,并实现自已的Listener在平时的单元测试,如果不使用RunWith注解,那么JUnit将会采用默认的执行类Suite执行,如下类:[java] view plain copy print?public class TestClass {      @Test public void  t1(){}  

2016-08-02 10:15:37 1870

转载 TCP/IP,socket,http关系

网络由下往上分为  物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。  通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层,  三者从本质上来说没有可比性,  socket则是对TCP/IP协议的封装和应用(程序员层面上)。  也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输

2016-08-02 09:41:13 333

java线程池概念.txt

线程安全,并发的知识有加深认知;当然,现在用过的东西并不是代表以后还能娴熟的使用,做好笔记非常重要; 1:必须明白为什么要使用线程池:(这点很重要)   a:手上项目所需,因为项目主要的目的是实现多线程的数据推送;需要创建多线程的话,那就要处理好线程安全的问题;因为项目需要,还涉及到排队下载的功能,所以就选择了线程池来管理线程以及线程池里面的任务队列workQueue来实现项目所需的功能;   b:在实际使用中,服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。为了防止资源不足,服务器应用程序需要采取一些办法来限制任何给定时刻处理的请求数目,尽可能减少创建和销毁线程的次数,特别是一些资源耗费比较大的线程的创建和销毁,尽量利用已有对象来进行服务,这就是“池化资源”技术产生的原因。 线程池主要用来解决线程生命周期开销问题和资源不足问题(这段是摘自网络) 2:如何创建一个线程池:    复制代码 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime = corePoolSize || !addIfUnderCorePoolSize(command)) {//新建线程并启动 if (runState == RUNNING && workQueue.offer(command)) {//添加任务到队列 if (runState != RUNNING || poolSize == 0) ensureQueuedTaskHandled(command);//添加到队列失败或已满,做拒接任务处理策略 } //若阻塞队列失败或已满;这里新建一个线程并启动做应急处理(这里就是用到了maximumPoolSize参数) else if (!addIfUnderMaximumPoolSize(command)) reject(command); // 若线程池的线程超过了maximumPoolSize;就做拒绝处理任务策略 } } 复制代码 --&gt;>继续跟踪代码到addIfUnderCorePoolSize(Runnable firstTask):函数名称就可以看出来这个函数要执行的什么;如果线程池的线程小于核心线程数corePoolSize就新建线程加入任务并启动线程【在今后的开发中尽量把需要做的功能在函数名体现出来】 复制代码 private boolean addIfUnderCorePoolSize(Runnable firstTask) { Thread t = null; final ReentrantLock mainLock = this.mainLock;//获取当前线程池的锁 mainLock.lock();//加锁 try { /* 这里线程池线程大小还需要判断一次;前面的判断过程中并没有加锁,因此可能在execute方法判断的时候poolSize小于corePoolSize,而判断完之后,在其他线程中又向线程池提交了任务,就可能导致poolSize不小于corePoolSize了,所以需要在这个地方继续判断 */ if (poolSize largestPoolSize) largestPoolSize = nt; } return t; } 复制代码 --&gt;>接下来定位worker类,看看线程池里的线程是如何执行的 上面的addIfUnderCorePoolSize(..)已经把线程启动了;现在就直接查看worker 的run()方法了 复制代码 public void run() { try { Runnable task = firstTask;//该线程的第一个任务,执行完后就从阻塞队列取任务执行 firstTask = null; while (task != null || (task = getTask()) != null) {//getTask()从队列去任务执行 runTask(task);//线程执行任务 task = null; } } finally { workerDone(this);//若任务全部执行完,就开始尝试去停止线程池;这部分代码就不再追踪下去,有兴趣的读者可以自己打开源码分析,不必害怕,学习大神们的编码方式,看源码能让你学习到很多 } } private void runTask(Runnable task) { final ReentrantLock runLock = this.runLock; runLock.lock(); try { //多次检查线程池有没有关闭 if (runState = STOP) thread.interrupt(); boolean ran = false; //这里就可以继承ThreadPoolExecutor,并覆盖beforeExecute(...)该方法,来做一些执行任务之前的统计工作或者用来保存正在执行的任务 beforeExecute(thread, task); try { task.run(); ran = true; //这里就可以继承ThreadPoolExecutor,并覆盖beforeExecute(...)该方法,来做一些执行任务完成之后的统计工作或者用来保存正在执行的任务 afterExecute(task, null); ++completedTasks;//统计总共执行的任务数 } catch (RuntimeException ex) { if (!ran) afterExecute(task, ex); throw ex; } } finally { runLock.unlock(); } } 复制代码 至此线程池基本的流程完了; 再说说我在项目中的使用: MyExtendThreadPoolExecutor 继承了 ThreadPoolExecutor,并覆盖了其中的一些方法 复制代码 public class MyExtendThreadPoolExecutor extends ThreadPoolExecutor{ public static Logger logger=LoggerFactory.getLogger(MyExtendThreadPoolExecutor.class); /** * 记录运行中任务 */ private LinkedBlockingQueue workBlockingQueue=new LinkedBlockingQueue(); public MyExtendThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); workBlockingQueue.add((GtdataBreakpointResumeDownloadThread)r);//保存在运行的任务 logger.info("Before the task execution"); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); workBlockingQueue.remove((GtdataBreakpointResumeDownloadThread)r);//移除关闭的任务 logger.info("After the task execution"); } /** * * Description: 正在运行的任务 * @return LinkedBlockingQueue * @author lishun */ public LinkedBlockingQueue getWorkBlockingQueue() { return workBlockingQueue; } } 复制代码 MyExtendThreadPoolExecutor pool = new MyExtendThreadPoolExecutor(3, 3,60L,TimeUnit.SECONDS,new LinkedBlockingQueue ()); //创建线程池 复制代码 public void addToThreadPool(DownloadRecord downloadRecord){ BlockingQueue waitThreadQueue = pool.getQueue();//Returns the task queue LinkedBlockingQueue workThreadQueue =pool.getWorkBlockingQueue();//Returns the running work GtdataBreakpointResumeDownloadThread downloadThread = new GtdataBreakpointResumeDownloadThread(downloadRecord);//需要执行的任务线程 if (!waitThreadQueue.contains(downloadThread)&&!workThreadQueue.contains(downloadThread)) {//判断任务是否存在正在运行的线程或存在阻塞队列,不存在的就加入线程池(这里的比较要重写equals()) Timestamp recordtime = new Timestamp(System.currentTimeMillis()); logger.info("a_workThread:recordId="+downloadRecord.getId()+",name="+downloadRecord.getName()+" add to workThreadQueue"); downloadThread.setName("th_"+downloadRecord.getName()); pool.execute(downloadThread);//添加到线程池 }else{ logger.info("i_workThread:recordId="+downloadRecord.getId()+",name="+downloadRecord.getName()+" in waitThreadQueue or workThreadQueue"); } }

2019-08-16

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除