package com.demo;

import org.hibernate.HibernateException;
import org.hibernate.classic.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; public final class HibernateUtil {
private static SessionFactory sessionFactory;//现实中需要考虑属性的线程安全问题
/*
创建线程局部变量threadLocal,用来保存Hibernate的Session
ThreadLocal在其中设置任何对象,该对象对特定的线程访问将是“全局”且“局部”
全局:意味着这个线程的任何地方都可以访问到
局部:每个线程拥有它自己的ThreadLocal变量,一个线程不能访问或修改其他线程的ThreadLocal变量
*/
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
//使用静态代码块 初始化Hibernate
static{
try{
Configuration cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
}catch (HibernateException ex) {
// throw new RuntimeException("Exception building SessionFactory: "
// + ex.getMessage(), ex);
}
}
//获得ThreadLocal对象管理的session实例
/*
* 单一实例:在系统中全局使用一个唯一的SessionFactory实例,主要原因是Factory只需要一个实例可以调用方法就可以
* 另一个方面取得SessionFactory需要的时间太久,每次都实例化,会过分得浪费系统CPU资源
* 每个线程和使用自身对应的数据库连接session:这里是为每个线程建立一个局部的变量来达到这个目的
*/
public synchronized static Session getSession(){//同步锁 排队等候访问
/*
里面执行先取得当前线程的ThreadLocalMap 然后将threadSession作为key将对应的值取出
*/
Session s = (Session)threadLocal.get();//s--线程 私有
if(s==null){// 判断当前线程有无放进去session
s = sessionFactory.openSession();//创建一个session
//将新打开的session实例保存到线程局部变量threadLocal中
threadLocal.set(s);//实际上放到当前线程的ThreadLocal中
}
return s;
}
//关闭session实例
//@throws HibernateException
public static void closeSession() throws HibernateException{
//从线程局部变量threadLocal中获取之前存入的Session实例
Session session = threadLocal.get();
threadLocal.set(null);
if(session!=null){
session.close();
}
}
//获得sessionFactory的实例
public static SessionFactory getSessionFactory(){
if(sessionFactory == null){
Configuration cfg = new Configuration().configure();
sessionFactory = cfg.buildSessionFactory();
}
return sessionFactory;
}
//关闭sessionFactory
public static void closeSessionFactory(){
if(!sessionFactory.isClosed()){ //避免潜在的多线程并发问题
sessionFactory.close();
}
}
}
/*
threadLocal.set(session);将新创建的对象的引用保存到各线程的一个map中,每个线程都有这样的一个map
执行threadLocal.get()时,各线程从自己的map中取出放进去的对象 取出的是各自的对象
顺便说一下: synchronized(时间换空间 同步-仅仅提供一份变量 让不同的线程去排队访问)
ThreadLocal(空间换时间 并发性-为每一个线程都提供一份变量 因为可以同时访问而互不影响)
* new Configuration.configure() 会在默认的路径下找hiberate.cfg.xml配置文件,请看源代码: Java代码 收藏代码
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
} 所以你应该是:
Java代码 收藏代码
Configuration.configure("/hiberate.cfg.xml") *Configuration是hibernate的入口,在新建一个Configuration的实例的时候,
*使用不带参数的configure ()方法,hibernate会在classpath里面查找配置文件;
*Configuration的configure ()方法还支持带参数的访问方式,你可以指定hbm.xml文件的位置,
*而不是使用默认的classpath下面的配置文件。应该指定配置文件的位置。/
**/
package com.demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; public class HibernateUtils { // SessionFactory全局只需要有一个就可以了
private static SessionFactory sessionFactory; static {
Configuration cfg = new Configuration();
// cfg.configure(); // 读取默认的配置文件(hibernate.cfg.xml)
// // cfg.configure("hibernate.cfg.xml"); // 读取指定位置的配置文件
// sessionFactory = cfg.buildSessionFactory(); // cfg.addResource("cn/itcast/a_helloworld/User.hbm.xml");
// cfg.addClass(User.class); // 去User类所在的包中查找名称为User,后缀为.hbm.xml的文件 // 初始化SessionFactory
sessionFactory = new Configuration()//
.configure()//
.buildSessionFactory(); } /**
* 获取全局唯一的SessionFactory
*
* @return
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
} /**
* 从全局唯一的SessionFactory中打开一个Session
*
* @return
*/
public static Session openSession() {
return sessionFactory.openSession();
}
}

ThreadLocal与Synchronized的更多相关文章

  1. 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结

    概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...

  2. 并发与同步 (一) ThreadLocal与Synchronized 用哪一个好

    ThreadLocal是什么? 历史 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以 ...

  3. 处理java多线程时线程安全问题 - ThreadLocal和Synchronized

    多线程在自动化测试中用的不多,也就是说我们用单线程可以完成大部分的自动化测试脚本. 主要有两个原因,首先是因为自动化测试首要考虑的是脚本的稳定性,所以一般会牺牲效率以保证脚本稳定,其次是由于局限于我们 ...

  4. 多线程学习三:Thread API,ThreadLocal,synchronized,volatile和Condition

    一.Thread API: setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 首先要了解什么是Thread. ...

  5. ThreadLocal 和Synchronized

    并发都用到, 两个都是解决了线程并发问题,区别呢? Synchronized  同步机制, 共有变量被多个线程使用,会出现线程不安全,所以,加锁,锁机制很多种,例如Synchronized, lock ...

  6. ThreadLocal与Synchronized区别

    ThreadLocal和Synchonized都用于解决多线程并发访问他们两者的区别:synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问,而ThreadLocal为每一 ...

  7. ThreadLocal 与 Synchronized区别

    相同:ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题.不同:Synchronized同步机制采用了“以时间换空间”的方式,仅提供一份变量,让不同的线程排队访问:而Thr ...

  8. ThreadLocal, volatile, synchronized, map, epoll, AQS简单总结

    ThreadLocal ThreadLocal主要是为了解决内存泄漏的问题,它是一种弱引用: 引用总共有四种,,我简单列一下: 强引用(Strong Reference):正常引用,根据垃圾回收算法, ...

  9. synchronized + volatile + ThreadLocal

    线程的共享 synchronized  +  volatile + ThreadLocal <1> synchronized 锁住的是对象,当用它来锁住一个类时,实际上也是锁的一个对象. ...

随机推荐

  1. 解决eclipse中web项目出现Project facet Java version 1.8 is not supported.的问题

    项目的jdk和tomcat的jdk版本不同,将eclipse-preference-server-runtime environments点击你要用的tomcat点击edit-jre选择和你项目对应的 ...

  2. redis + Tomcat 8 的session共享解决

    如果英文不错的看,建议直接看官网吧,官网写的挺清楚.下面的内容是转载的一篇文章,自己补充了一些,供大家参考,也欢迎大家一起讨论 官方截止到2015-10-12前是不支持Tomcat8的,详情见官网:h ...

  3. Maven内置属性及使用

    Maven共有6类属性: 内置属性(Maven预定义,用户可以直接使用) ${basedir}表示项目根目录,即包含pom.xml文件的目录; ${version}表示项目版本; ${project. ...

  4. 自己用图片做的可旋转、不确定进度的ProgressBar

    今天看到一个人将图片写个动画,然后就当做progressbar用了,思路挺棒的. 原文地址:http://blog.csdn.net/sweetvvck/article/details/2388253 ...

  5. [Android Pro] 终极组件化框架项目方案详解

    cp from : https://blog.csdn.net/pochenpiji159/article/details/78660844 前言 本文所讲的组件化案例是基于自己开源的组件化框架项目g ...

  6. Windows Power Shell简介

    Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能. 它引入了许多非常有用的新概念,从而进一步扩展了您在 W ...

  7. 用SLF4j/Logback打印日志-2

    本篇主要介绍logback的输出源配置,logback默认提供了很多输出源,但是用的最多的是这几种: OutputStreamAppender 日志输出到一个二进制流,可以通过 <encoder ...

  8. verilog语法实例学习(10)

    常用的时序电路介绍 T触发器和JK触发器 在D触发器输入端添加一些简单的逻辑电路,可以生成另一种类型的存储元件.比如下图所示的T触发器.该电路有一个上升沿触发的触发器和两个与门,一个或门,以及一个反相 ...

  9. 浅谈 Boost.Asio 的多线程模型

    Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法. 另一种支持多 ...

  10. 快速书写常见的 Kotlin 代码 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...