• ThreadLocal(在一个线程中共享数据)


    ThreadLocal

      在"事务传递Connection"参数案例中,我们必须传递Connection对象,才可以完成整个事务操作.如果不传递参数,是否可以完成?在JDK中给我们提供了一个工具类ThreadLocal.此类可以在一个线程中共享数据

    java.lang.ThreadLocal:该类提供了线程局部(thread-local)变量,用于在当前线程中共享数据.

    ThreadLocal

    java.lang.ThreadLocal该类提供了线程局部(thread-local)变量,用于在当前线程中共享数据,ThreadLocal工具类底层就是一个相当于一个Map,key存放的当前线程,value存放需要共享的数据.

    package com.qingmu;
    
    /**
     * @Auther:qingmu
     * @Description:脚踏实地,只为出人头地
     * @Date:Created in 16:08 2019/5/25
     */
    public class ThreadLocalTest {
        public static void main(String[] args) {
            ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
            stringThreadLocal.set("青木");
            System.out.println(stringThreadLocal.get());
    
            new Thread(()->
                    System.out.println(stringThreadLocal.get())).start();
        }
    }

    结果为:

    总结:向ThreadLocal中添加的数据只能在当前线程中使用.

    小案例的应用:

    工具类

    public class C3P0Utils {
        //创建一个C3P0的连接池对象(使用c3p0-config.xml中default-config标签中对应的参数)
        public static DataSource ds = new ComboPooledDataSource();
        //给当前线程绑定 连接
        private static ThreadLocal<Connection> local = new ThreadLocal<Connection>();
        /**
         * 获得一个连接
         */
        public static Connection getConnection(){
            try {
        //#1从当前线程中, 获得已经绑定的连接
                service层
                Connection conn = local.get();
                if(conn == null){
            //#2 第一次获得,绑定内容 – 从连接池获得
                    conn = ds.getConnection();
              //#3 将连接存 ThreadLocal
                    local.set(conn);
                }
                return conn; //获得连接
            } catch (Exception e) {
          //将编译时异常 转换 运行时 , 以后开发中运行时异常使用比较多的。
                throw new RuntimeException(e);
    /*
    类与类之间 进行数据交换时,可以使用return返回值。也可以使用自定义异常返回值,调用者try{}
    catch(e){ e.getMessage() 获得需要的数据}
    此处可以编写自定义异常。
    */
    //throw new MyConnectionException(e);
            }
        }
    }

    service层

    public class AccountService {
        /**
         * 事务管理方式:向下传递Connection。有侵入性。使用DBUtils
         * 业务层事务管理转账的方法
         * @param from
         * @param to
         * @param money
         */
        public void transfer(String from, String to, double money) {
            //调用dao层
            AccountDao accountDao = new AccountDao();
            //DBUtils进行事务处理的原理,是在Service层获得连接,以保证事务处理过程中的Connection对象为同一个Connection。
            //因为必须保证连接为同一个连接,所以在业务层获得连接,再将连接传递到持久层,代码具有侵入性。
            //DBUtils使用的方法
            Connection conn = null;
            try {
                //获得连接
                conn = C3P0Utils.getConnection();
                //设置事务不自动提交
                conn.setAutoCommit(false);
                //调用持久层
                accountDao.outMoney(from,money);
                //如果有异常
    //int a = 1 / 0 ;
                accountDao.inMoney(to,money);
                //提交事务,并安静的关闭连接
                DbUtils.commitAndCloseQuietly(conn);
            } catch (SQLException e) {
            //有异常出现时,回滚事务,并安静的关闭连接
                DbUtils.rollbackAndCloseQuietly(conn);
                e.printStackTrace();
            }
        }
    }

    dao层

    public class AccountDao {
        /**
         * 付款方法
         * @param from 付款人
         * @param money 金额
         */
        public void outMoney(String from, double money) {
            QueryRunner qr = new QueryRunner();
            try {
                Connection conn = C3P0Utils.getConnection();
                String sql = "update account set money = money - ? where name = ?";
                qr.update(conn, sql, money,from);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        /**
         * 收款方法
         * @param to 收款人
         * @param money 金额
         */
        public void inMoney(String to, double money) {
            QueryRunner qr = new QueryRunner();
            try {
                Connection conn = C3P0Utils.getConnection();
                String sql = "update account set money = money + ? where name = ?";
                qr.update(conn, sql, money,to);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    AngularJS----基本操作
    AngularJS------认识AngularJS
    利用JsonConvert.SerializeObject()实现类对象的json化
    数据结构(C语言第2版)-----数组,广义表,树,图
    数据结构(c语言第2版)-----了解链表,栈,队列,串
    php 获取开始日期与结束日期之间所有日期
    城市列表取汉字的第一个字的首字母并排序功能
    php订单号的生成
    PHP代码中出现中文乱码怎么办?
    PHP开发丨3个简单的方法处理emoji表情
  • 原文地址:https://www.cnblogs.com/qingmuchuanqi48/p/10922856.html
Copyright © 2020-2023  润新知