ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:225.86KB ,
资源ID:8437798      下载积分:10 金币
验证码下载
登录下载
邮箱/手机:
图形码:
验证码: 获取验证码
温馨提示:
支付成功后,系统会自动生成账号(用户名为邮箱或者手机号,密码是验证码),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8437798.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请。


权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4009-655-100;投诉/维权电话:18658249818。

注意事项

本文(之漫谈使用ThreadLocal改进你的层次的划分.docx)为本站上传会员【pc****0】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

之漫谈使用ThreadLocal改进你的层次的划分.docx

1、一、什么是ThreadLocal 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自

2、己的副本,而不会影响其它线程所对应的副本。 从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。 线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。 所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。 ThreadLocal的接口方法 ThreadLocal类接口很简单,只有4个方法,我们先来了解一下: ²  void set(Ob

3、ject value) 设置当前线程的线程局部变量的值。 ²  public Object get() 该方法返回当前线程所对应的线程局部变量。 ²  public void remove() 将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。 ²  protected ObjectinitialValue() 返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖

4、而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。 值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。 一、来看一个实际案例 2.1 同一Service方法中调用多个Dao方法 可以看到,我们有一个Service方法,在该Service方法中调用多个Dao方

5、法,所有在该Service方法中的的Dao都处于同一事务中。 该Service方法结束后,提交事务; 该Service方法中有任何错,回滚事务; 2.2 传统的做法 来看下面这段伪代码 Service层代码: public void serviceMethod(){ Connection conn=null; try{ Connection conn=getConnection(); conn.setAutoCommit(false); Dao1 dao1=new Dao1(conn); dao1.doSomething(); Dao2 dao2=new Dao2(c

6、onn); dao2.doSomething(); Dao3 dao3=new Dao3(conn); dao3.doSomething();         mit(); }catch(Exception e){     try{     conn.rollback(); }catch(Exception ex){} }finally{ try{ conn.setAutoCommit(true); }catch(Exception e){}     try{     if(conn!=null){     conn.close();     conn=null

7、 } }catch(Exception e){} } } 每个Dao层的代码: Class Dao1{ private Connection conn=null; public Dao1(Connection conn){     this.conn=conn; } public void doSomething(){     PreparedStatement pstmt=null;     try{         pstmt=conn.preparedStatement(sql);         pstmt.execute…         … }c

8、atch(Exception e){     log.error(e,”Exeception occurred in Dao1.doSomething():”+e.getMessage,e); }finally{     try{         if(pstmt!=null){             pstmt.close();             pstmt=null; }     }catch(Exception e){} } } } 如果我一个Service方法有调用一堆dao方法,先不说这样写首先破坏了OOP的封装性原则,如果有一个dao多关了一个con

9、n,那就会导致其它的dao得到的conn为null,这种事在这样的写法下由其当你还有业务逻辑混合在一起时很容易发生。 笔者曾经遇见过2个项目,出现out of memory或者是connection pool has been leakage,经查代码就是在每个dao中多关或者在service层中漏关,或者是每个dao有自己的conntionconn=getConnection(),然后还跑到Service层里去关这个connection(那关什么,关个P关!)。 当然,如果你说你在写法上绝对promise绝对注意这样的问题不会发生,但是我们来看看下面的这种做法,是否会比上面这个写法更好呢

10、  2.3 Spring中的做法 先来看Spring中的写法。 大家应该都很熟悉Spring中的写法了,来看一下它是怎么解决的。 Service层 public void serviceMethod(){ try{     //aop 自动加入connection,并且将conn.setAutoCommit(false); dao1.doSomething(); dao2.doSomething(); dao3.doSomething(); }catch(Exception e){     //aop 自动加入rollback }finally{     //ao

11、p自动加入conn.setAutoCommit(true)     //aop 自动加入conn.close(); }   这边我们不讲AOP,因为用类反射结合xml很容易将aop 自动。。。这些东西加入我们的代码中去是不是?我们只管写dao方法,service方法,不需要关心在哪边commit哪边rollback何时connection,spring的声明式事务会帮我们负责,这种风格我们称为“优雅”,各层间耦合度极大程度上的降低,封装性好。 因此,我们可以总结出下面这些好处: ²  Service层的方法只管开启事务(如果讲究点的还会设一个Transaction); ²  在该

12、Service层中的所有dao使用该service方法中开启的事务(即connection); ²  Dao中每次只管getCurrentConnection(获取当前的connection),与进行数据处理 ²  Dao层中如果发生错误就抛回Service层 ²  Service层中接到exception,在catch{}中rollback,在try{}未尾commit,在finally块中关闭整个connection。 这。。。就是我们所说的ThreadLocal。 举个更实际的例子再次来说明ThreadLocal: 我们有3个用户访问同一个service方法,该service

13、方法内有3个dao方法为一个完整事务,那么整个web容器内只因该有3个connection,并且每个connection之间的状态,彼此“隔离”。 我们下面一起来看我们如何用代码实现类似于Spring的这种做法。 首先,根据我们的ThreadLocal的概念,我们先声明一个ConnectionManager的类。 2.4 利用ThreadLocal制作ConnectionManager public class ConnectionManager {          private static ThreadLocal tl = new ThreadLocal();       

14、   private static Connection conn = null;          public static void BeginTrans(boolean beginTrans) throws Exception {                    if (tl.get() == null || ((Connection) tl.get()).isClosed()) {                             conn = SingletonDBConnection.getInstance().getConnection();        

15、                     conn = new ConnectionSpy(conn);                             if (beginTrans) {                                      conn.setAutoCommit(false);                             }                             tl.set(conn);                    }          }          public static Con

16、nection getConnection() throws Exception {                    return (Connection) tl.get();          }          public static void close() throws SQLException {                    try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Excepti

17、on e) {                    }                    ((Connection) tl.get()).close();                    tl.set(null);          }          public static void commit() throws SQLException {                    try {                             ((Connection) tl.get()).commit();                    }

18、catch (Exception e) {                    }                    try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Exception e) {                    }          }          public static void rollback() throws SQLException {                

19、    try {                             ((Connection) tl.get()).rollback();                    } catch (Exception e) {                    }                    try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Exception e) {               

20、     }          } } 2.5 利用ThreadLocal改造Service与Dao层 Service层(注意红色标粗-好粗yeah,的地方) package sky.org.service.impl; public class StudentServiceImpl implements StudentService {          public void addStudent(Student std) throws Exception {                    StudentDAO studentDAO = new StudentDAOI

21、mpl();                    ClassRoomDAO classRoomDAO = new ClassRoomDAOImpl();                    try {                             ConnectionManager.BeginTrans(true);                             studentDAO.addStudent(std);                             classRoomDAO                               

22、                 .addStudentClassRoom(std.getClassRoomId(), std.getsNo());                             ConnectionMmit();                    } catch (Exception e) {                             try {                                      ConnectionManager.rollback();                             }

23、catch (Exception de) {                             }                             throw new Exception(e);                    }finally {                             try {                                      ConnectionManager.close();                             } catch (Exception e) {         

24、                    }                    }          } } Look,如果我把上述标粗(没有加红色)的地方,全部用AOP的方式从这块代码的外部“切”进去。。。是不是一个Spring里的Service方法就诞生了? 下面来看一个完整的例子 2.6 使用ThreadLocal分离Service、DAO层 先来看表结构: T_Student表 T_ClassRoom表 T_Student_ClassRoom表 需求: 很简单,T_ClassRoom表里已经有值了,在插入T_Student表的数据时同时要给这个学生

25、分配一个班级并且插入T_Student_ClassRoom表,这就是一个事务,这两步中有任何一步出错,事务必须回滚。 看来工程的结构吧: 下面开始放出所有源代码: 2.6.1 ConnectionManager类 package sky.org.util.db; import java.sql.*; public class ConnectionManager {          private static ThreadLocal tl = new ThreadLocal();          private static Connection conn =

26、null;          public static void BeginTrans(boolean beginTrans) throws Exception {                    if (tl.get() == null || ((Connection) tl.get()).isClosed()) {                             conn = DBConnection.getInstance().getConnection();                             conn = new ConnectionSpy

27、conn);                             if (beginTrans) {                                      conn.setAutoCommit(false);                             }                             tl.set(conn);                    }          }          public static Connection getConnection() throws Exception {  

28、                 return (Connection) tl.get();          }          public static void close() throws SQLException {                    try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Exception e) {                    }                

29、    ((Connection) tl.get()).close();                    tl.set(null);          }          public static void commit() throws SQLException {                    try {                             ((Connection) tl.get()).commit();                    } catch (Exception e) {                    }  

30、                  try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Exception e) {                    }          }          public static void rollback() throws SQLException {                    try {                             ((Conne

31、ction) tl.get()).rollback();                    } catch (Exception e) {                    }                    try {                             ((Connection) tl.get()).setAutoCommit(true);                    } catch (Exception e) {                    }          } } 2.6.2 DBConnection类 pa

32、ckage sky.org.util.db; public class DBConnection {          private static DBConnection instance = null;          private static String driverClassName = null;          private static String connectionUrl = null;          private static String userName = null;          private static String pa

33、ssword = null;          private static Connection conn = null;          private static Properties jdbcProp = null;          private DBConnection() {          }          private static Properties getConfigFromPropertiesFile() throws Exception {                    Properties prop = null;       

34、             prop = JdbcProperties.getPropObjFromFile();                    return prop;          }          private static void initJdbcParameters(Properties prop) {                    driverClassName = prop.getProperty(Constants.DRIVER_CLASS_NAME);                    connectionUrl = prop.getP

35、roperty(Constants.CONNECTION_URL);                    userName = prop.getProperty(Constants.DB_USER_NAME);                    password = prop.getProperty(Constants.DB_USER_PASSWORD);          }          private static void createConnection() throws Exception {                    Class.forName(d

36、riverClassName);                    conn = DriverManager.getConnection(connectionUrl, userName, password);          }          public static Connection getConnection() throws Exception {                    return conn;          }          public synchronized static DBConnection getInstance()th

37、rows Exception{                    if (instance == null) {                             jdbcProp = getConfigFromPropertiesFile();                             instance = new DBConnection();                    }                    initJdbcParameters(jdbcProp);                    createConnection(

38、);                    return instance;          } } 2.6.3 JdbcProperties类 package sky.org.util.db; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import .URL; import java.util.*; public c

39、lass JdbcProperties {          private static Log logger = LogFactory.getLog(JdbcProperties.class);          public static Properties getPropObjFromFile() {                    Properties objProp = new Properties();                    ClassLoader classLoader = Thread.currentThread()             

40、                         .getContextClassLoader();                    URL url = classLoader.getResource(Constants.JDBC_PROPERTIES_FILE);                    if (url == null) {                             classLoader = ClassLoader.getSystemClassLoader();                             url = classLoad

41、er.getResource(Constants.JDBC_PROPERTIES_FILE);                    }                    File file = new File(url.getFile());                    InputStream inStream = null;                    try {                             inStream = new FileInputStream(file);                             ob

42、jProp.load(inStream);                    } catch (FileNotFoundException e) {                             objProp = null;                             e.printStackTrace();                    } catch (IOException e) {                             e.printStackTrace();                    } finally {

43、                             try {                                      if (inStream != null) {                                                inStream.close();                                                inStream = null;                                      }                             }

44、catch (Exception e) {                             }                    }                    return objProp;          } } 2.6.4 Resource目录下的jdbc.properties jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.databaseURL=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8 jdbc

45、username=mysql jdbc.password=password_1 2.6.5 StudentService接口 package sky.org.service; import java.util.List; import java.util.Vector; import sky.org.bean.*; public interface StudentService {          public void addStudent(Student std) throws Exception; } 2.6.6 StudentServiceImpl类 pack

46、age sky.org.service.impl; import java.util.ArrayList; import java.util.List; import java.util.Vector; import sky.org.util.db.ConnectionManager; import sky.org.util.*; import sky.org.bean.*; import sky.org.dao.*; import sky.org.dao.impl.*; import sky.org.service.*; public class StudentServi

47、ceImpl implements StudentService {            public void addStudent(Student std) throws Exception {                    StudentDAO studentDAO = new StudentDAOImpl();                    ClassRoomDAO classRoomDAO = new ClassRoomDAOImpl();                    try {                             Conn

48、ectionManager.BeginTrans(true);                             studentDAO.addStudent(std);                             classRoomDAO                                                .addStudentClassRoom(std.getClassRoomId(), std.getsNo());                             ConnectionMmit();                

49、    } catch (Exception e) {                             try {                                      ConnectionManager.rollback();                             } catch (Exception de) {                             }                             throw new Exception(e);                    } finally {                             try {                                      ConnectionManager.close();                             } catch (Exception e) {                             }                    }          } } 2.6.7 ClassRoomDAO接口 package sky.org.dao

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服