温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

好程序员Java学习路线分享MyBatis之线程优化

发布时间:2020-06-12 21:47:52 来源:网络 阅读:182 作者:wx5d42865f47214 栏目:编程语言

  好程序员Java学习路线分享MyBatis之线程优化,我们的项目存在大量用户同时访问的情况,那么就会出现大量线程并发访问数据库,这样会带来线程同步问题,本章我们将讨论MyBatis的线程同步问题和优化方法。

 

MyBatis的线程同步问题

MyBatis需要通过SqlSession实现数据库操作,而SQLSession内部的实现需要使用JDBCConnection连接对象,而Connection对象是非线程安全的,当多个线程同时

访问时,就可能出现线程同步的问题。

线程同步的解决方法

我们前面学习过解决线程同步的方法是:锁机制

我们可以给所有数据库相关方法或代码添加synchronized关键字,本质上是让所有线程排队执行这些操作。

好程序员Java学习路线分享MyBatis之线程优化

这样解决了线程同步问题,但是会带来执行效率的降低,如果大量的用户访问时会导致长时间的等待,所以今天我们将学习另一种解决方法。

ThreadLocal解决线程同步

ThreadLocal(线程局部变量),可以为每个线程创建对象的副本,这样就不存在多线程访问一个对象的情况,以空间换时间,效率高,速度快,但是内存空间消耗更大。

好程序员Java学习路线分享MyBatis之线程优化

ThreadLocal的用法

创建方法:

ThreadLocal<数据的类型> threadLocal = new ThreadLocal<数据类型>();

数据的类型是每个线程中需要保存数据的类型

数据存取:

void set(Object 数据将数据和当前线程绑定起来

Object get() 从当前线程中获得绑定的数据

 

Session线程安全的优化方法

1)创建ThreadLocal来保存SqlSession

2)编写获得SqlSession的方法

1)调用ThreadLocalget方法来获得SqlSession

2)如果SqlSession对象为null,调用工厂来创建SqlSession,使用ThreadLocalset方法保存到线程中,返回SqlSession对象

3)如果SqlSession对象不为null,就直接返回

示例代码:

/**

 * MyBatis工具类

 * 用于获得当前线程中的SqlSession

 * 使用ThreadLocal解决线程安全问题

 */

public class MyBatisUtils {

 

    public static final String CONFIG_FILENAME = "mybatis-config.xml";

    //使用ThreadLocal保存SQLSession对象

    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();

    //SqlSession的工厂,单例

    private static SqlSessionFactory factory = null;

    /**

     * 创建工厂

     */

    public static void buildFactory(){

        try {

            factory = new SqlSessionFactoryBuilder().build(

                    Resources.getResourceAsStream(CONFIG_FILENAME));

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    //在静态代码块中执行,保证工厂的创建只执行一次

    static{

        buildFactory();

    }

    /**

     * 从当前线程中获得Session

     * @return

     */

    public static SqlSession getSession(){

        //ThreadLocal获得线程中的SqlSession

        SqlSession sqlSession = threadLocal.get();

        if(sqlSession == null){

            //如果SqlSession为空,创建SqlSession

            if(factory == null){

                buildFactory();

            }

            sqlSession = factory.openSession();

            //把新创建的SqlSession,存入到ThreadLocal,绑定到线程中

            threadLocal.set(sqlSession);

        }

        return sqlSession;

    }

    /**

     * 关闭Session

     */

    public static void closeSession(){

        //ThreadLocal获得线程中的SqlSession

        SqlSession sqlSession = threadLocal.get();

        if(sqlSession != null){

            //关闭会话

            sqlSession.close();

            //设置为nullgc会尽快回收

            sqlSession = null;

            //删除掉ThreadLocal中的SqlSession

            threadLocal.set(null);

        }

    }

}

 

总结

线程同步是进行JavaEE开发需要重点考虑的问题,MyBatisSQLSession有线程同步问题,使用ThreadLocal为每个线程绑定自己的SQLSession副本,可以解决线程同步问题,同时不会降低程序执行效率。

 


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI