??xml version="1.0" encoding="utf-8" standalone="yes"?>一本久道中文字幕精品亚洲嫩,国产精品一区三区在线观看,黑人久久a级毛片免费观看http://www.aygfsteel.com/jimingminlovefly/category/50450.htmlzh-cnFri, 30 Jan 2015 15:59:30 GMTFri, 30 Jan 2015 15:59:30 GMT60深入研究java.lang.ThreadLocalc?/title><link>http://www.aygfsteel.com/jimingminlovefly/articles/422575.html</link><dc:creator>计明?/dc:creator><author>计明?/author><pubDate>Fri, 30 Jan 2015 03:07:00 GMT</pubDate><guid>http://www.aygfsteel.com/jimingminlovefly/articles/422575.html</guid><wfw:comment>http://www.aygfsteel.com/jimingminlovefly/comments/422575.html</wfw:comment><comments>http://www.aygfsteel.com/jimingminlovefly/articles/422575.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jimingminlovefly/comments/commentRss/422575.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jimingminlovefly/services/trackbacks/422575.html</trackback:ping><description><![CDATA[<div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;">一、概q?/strong></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;"></strong> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal是什么呢Q其实ThreadLocalq是一个线E的本地实现版本Q它q不是一个ThreadQ而是threadlocalvariable(U程局部变?。也许把它命名ؓThreadLocalVar更加合适。线E局部变?ThreadLocal)其实的功用非常简单,是为每一个用该变量的线E都提供一个变量值的副本Q是Java中一U较为特D的U程l定机制Q是每一个线E都可以独立地改变自q副本Q而不会和其它U程的副本冲H?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">从线E的角度看,每个U程都保持一个对其线E局部变量副本的隐式引用Q只要线E是zd的ƈ?ThreadLocal 实例是可讉K的;在线E消׃后,其线E局部实例的所有副本都会被垃圾回收Q除非存在对q些副本的其他引用)?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">通过ThreadLocal存取的数据,L与当前线E相养I也就是说QJVM 为每个运行的U程Q绑定了U有的本地实例存取空_从而ؓ多线E环境常出现的ƈ发访问问题提供了一U隔L制?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal是如何做Cؓ每一个线E维护变量的副本的呢Q其实实现的思\很简单,在ThreadLocalcM有一个MapQ用于存储每一个线E的变量的副本?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">概括h_对于多线E资源共享的问题Q同步机刉用了“以时间换I间”的方式,而ThreadLocal采用?#8220;以空间换旉”的方式。前者仅提供一份变量,让不同的U程排队讉KQ而后者ؓ每一个线E都提供了一份变量,因此可以同时讉K而互不媄响?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;">二、API说明</strong></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal()</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">          创徏一个线E本地变量?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">T get()</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">          q回此线E局部变量的当前U程副本中的|如果q是U程W一ơ调用该ҎQ则创徏q初始化此副本?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">protected  T initialValue()</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">          q回此线E局部变量的当前U程的初始倹{最多在每次讉KU程来获得每个线E局部变量时调用此方法一ơ,即线E第一ơ?get() Ҏ讉K变量的时候。如果线E先?get Ҏ调用 set(T) ҎQ则不会在线E中再调?initialValue Ҏ?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">   若该实现只返?nullQ如果程序员希望线E局部变量初始化?null 以外的某个|则必Mؓ ThreadLocal 创徏子类Qƈ重写此方法。通常Q将使用匿名内部cRinitialValue 的典型实现将调用一个适当的构造方法,q返回新构造的对象?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">void remove()</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">          U除此线E局部变量的倹{这可能有助于减线E局部变量的存储需求。如果再ơ访问此U程局部变量,那么在默认情况下它将拥有?initialValue?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">void set(T value)</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">          此U程局部变量的当前U程副本中的D|ؓ指定倹{许多应用程序不需要这功能,它们只依赖于 initialValue() Ҏ来设|线E局部变量的倹{?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">在程序中一般都重写initialValueҎQ以l定一个特定的初始倹{?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;">三、典型实?/strong></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">1、Hiberante的Session 工具cHibernateUtil</div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">q个cLHibernate官方文档中HibernateUtilc,用于session理?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><div style="margin: 0px;"><div style="padding: 5px; margin: 0px; border: 1px solid #aaaaaa; background-color: #f5f5f5;"><div style="margin: 0px;">public class HibernateUtil {</div><div style="margin: 0px;">    private static Log log = LogFactory.getLog(HibernateUtil.class);</div><div style="margin: 0px;">    private static final SessionFactory sessionFactory;     //定义SessionFactory</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    static {<br style="padding: 0px; margin: 0px;" />        try {<br style="padding: 0px; margin: 0px;" />            // 通过默认配置文ghibernate.cfg.xml创徏SessionFactory<br style="padding: 0px; margin: 0px;" />            sessionFactory = new Configuration().configure().buildSessionFactory();<br style="padding: 0px; margin: 0px;" />        } catch (Throwable ex) {<br style="padding: 0px; margin: 0px;" />            log.error("初始化SessionFactoryp|Q?, ex);<br style="padding: 0px; margin: 0px;" />            throw new ExceptionInInitializerError(ex);<br style="padding: 0px; margin: 0px;" />        }<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"><br style="padding: 0px; margin: 0px;" />    //创徏U程局部变量sessionQ用来保存Hibernate的Session<br style="padding: 0px; margin: 0px;" />    public static final ThreadLocal session = new ThreadLocal();</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    /**<br style="padding: 0px; margin: 0px;" />     * 获取当前U程中的Session<br style="padding: 0px; margin: 0px;" />     * @return Session<br style="padding: 0px; margin: 0px;" />     * @throws HibernateException<br style="padding: 0px; margin: 0px;" />     */<br style="padding: 0px; margin: 0px;" />    public static Session currentSession() throws HibernateException {<br style="padding: 0px; margin: 0px;" />        Session s = (Session) session.get();<br style="padding: 0px; margin: 0px;" />        // 如果Sessionq没有打开Q则新开一个Session<br style="padding: 0px; margin: 0px;" />        if (s == null) {<br style="padding: 0px; margin: 0px;" />            s = sessionFactory.openSession();<br style="padding: 0px; margin: 0px;" />            session.set(s);         //新开的Session保存到线E局部变量中<br style="padding: 0px; margin: 0px;" />        }<br style="padding: 0px; margin: 0px;" />        return s;<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    public static void closeSession() throws HibernateException {<br style="padding: 0px; margin: 0px;" />        //获取U程局部变量,q强制{换ؓSessioncd<br style="padding: 0px; margin: 0px;" />        Session s = (Session) session.get();<br style="padding: 0px; margin: 0px;" />        session.set(null);<br style="padding: 0px; margin: 0px;" />        if (s != null)<br style="padding: 0px; margin: 0px;" />            s.close();<br style="padding: 0px; margin: 0px;" />    }<br style="padding: 0px; margin: 0px;" />}</div></div></div></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">在这个类中,׃没有重写ThreadLocal的initialValue()ҎQ则首次创徏U程局部变量session其初始gؓnullQ第一ơ调用currentSession()的时候,U程局部变量的get()Ҏ也ؓnull。因此,对session做了判断Q如果ؓnullQ则新开一个SessionQƈ保存到线E局部变量session中,q一步非常的关键Q这也是“public static final ThreadLocal session = new ThreadLocal()”所创徏对象session能强制{换ؓHibernate Session对象的原因?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">2、另外一个实?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">创徏一个BeanQ通过不同的线E对象设|Bean属性,保证各个U程Bean对象的独立性?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="padding: 5px; margin: 0px; border: 1px solid #aaaaaa; background-color: #f5f5f5;"><div style="margin: 0px;">/**<br style="padding: 0px; margin: 0px;" /> * Created by IntelliJ IDEA.<br style="padding: 0px; margin: 0px;" /> * User: leizhimin<br style="padding: 0px; margin: 0px;" /> * Date: 2007-11-23<br style="padding: 0px; margin: 0px;" /> * Time: 10:45:02<br style="padding: 0px; margin: 0px;" /> * 学生<br style="padding: 0px; margin: 0px;" /> */<br style="padding: 0px; margin: 0px;" />public class Student {<br style="padding: 0px; margin: 0px;" />    private int age = 0;   //q龄</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    public int getAge() {<br style="padding: 0px; margin: 0px;" />        return this.age;<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    public void setAge(int age) {<br style="padding: 0px; margin: 0px;" />        this.age = age;<br style="padding: 0px; margin: 0px;" />    }<br style="padding: 0px; margin: 0px;" />}</div></div></div></div></div></div></div></div></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="padding: 5px; margin: 0px; border: 1px solid #aaaaaa; background-color: #f5f5f5;"><div style="margin: 0px;">/**<br style="padding: 0px; margin: 0px;" /> * Created by IntelliJ IDEA.<br style="padding: 0px; margin: 0px;" /> * User: leizhimin<br style="padding: 0px; margin: 0px;" /> * Date: 2007-11-23<br style="padding: 0px; margin: 0px;" /> * Time: 10:53:33<br style="padding: 0px; margin: 0px;" /> * 多线E下试E序<br style="padding: 0px; margin: 0px;" /> */<br style="padding: 0px; margin: 0px;" />public class ThreadLocalDemo implements Runnable {<br style="padding: 0px; margin: 0px;" />    //创徏U程局部变量studentLocalQ在后面你会发现用来保存Student对象<br style="padding: 0px; margin: 0px;" />    private final static ThreadLocal studentLocal = new ThreadLocal();</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    public static void main(String[] agrs) {<br style="padding: 0px; margin: 0px;" />        ThreadLocalDemo td = new ThreadLocalDemo();<br style="padding: 0px; margin: 0px;" />        Thread t1 = new Thread(td, "a");<br style="padding: 0px; margin: 0px;" />        Thread t2 = new Thread(td, "b");<br style="padding: 0px; margin: 0px;" />        t1.start();<br style="padding: 0px; margin: 0px;" />        t2.start();<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    public void run() {<br style="padding: 0px; margin: 0px;" />        accessStudent();<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    /**<br style="padding: 0px; margin: 0px;" />     * CZ业务ҎQ用来测?br style="padding: 0px; margin: 0px;" />     */<br style="padding: 0px; margin: 0px;" />    public void accessStudent() {<br style="padding: 0px; margin: 0px;" />        //获取当前U程的名?br style="padding: 0px; margin: 0px;" />        String currentThreadName = Thread.currentThread().getName();<br style="padding: 0px; margin: 0px;" />        System.out.println(currentThreadName + " is running!");</div><div style="margin: 0px;">        //产生一个随机数q打?br style="padding: 0px; margin: 0px;" />        Random random = new Random();<br style="padding: 0px; margin: 0px;" />        int age = random.nextInt(100);<br style="padding: 0px; margin: 0px;" />        System.out.println("thread " + currentThreadName + " set age to:" + age);</div><div style="margin: 0px;">        //获取一个Student对象Qƈ随机数q龄插入到对象属性中<br style="padding: 0px; margin: 0px;" />        Student student = getStudent();<br style="padding: 0px; margin: 0px;" />        student.setAge(age);<br style="padding: 0px; margin: 0px;" />        System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge());<br style="padding: 0px; margin: 0px;" />        try {<br style="padding: 0px; margin: 0px;" />            Thread.sleep(500);<br style="padding: 0px; margin: 0px;" />        }<br style="padding: 0px; margin: 0px;" />        catch (InterruptedException ex) {<br style="padding: 0px; margin: 0px;" />            ex.printStackTrace();<br style="padding: 0px; margin: 0px;" />        }<br style="padding: 0px; margin: 0px;" />        System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge());<br style="padding: 0px; margin: 0px;" />    }</div><div style="margin: 0px;"> </div><div style="margin: 0px;">    protected Student getStudent() {<br style="padding: 0px; margin: 0px;" />        //获取本地U程变量q强制{换ؓStudentcd<br style="padding: 0px; margin: 0px;" />        Student student = (Student) studentLocal.get();<br style="padding: 0px; margin: 0px;" />        //U程首次执行此方法的时候,studentLocal.get()肯定为null<br style="padding: 0px; margin: 0px;" />        if (student == null) {<br style="padding: 0px; margin: 0px;" />            //创徏一个Student对象Qƈ保存到本地线E变量studentLocal?br style="padding: 0px; margin: 0px;" />            student = new Student();<br style="padding: 0px; margin: 0px;" />            studentLocal.set(student);<br style="padding: 0px; margin: 0px;" />        }<br style="padding: 0px; margin: 0px;" />        return student;<br style="padding: 0px; margin: 0px;" />    }<br style="padding: 0px; margin: 0px;" />}</div></div></div></div></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">q行l果Q?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><div style="margin: 0px;"><div style="padding: 4px; margin: 0px; border: 1px solid #cccccc; font-size: 10pt; width: 705.59375px; color: #000000; word-break: break-all; line-height: 16px; font-family: verdana, 宋体; background-color: #eeeeee;">a is running! <br style="padding: 0px; margin: 0px;" />thread a set age to:76 <br style="padding: 0px; margin: 0px;" />b is running! <br style="padding: 0px; margin: 0px;" />thread b set age to:27 <br style="padding: 0px; margin: 0px;" />thread a first read age is:76 <br style="padding: 0px; margin: 0px;" />thread b first read age is:27 <br style="padding: 0px; margin: 0px;" />thread a second read age is:76 <br style="padding: 0px; margin: 0px;" />thread b second read age is:27 </div></div></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">可以看到a、b两个U程age在不同时L印的值是完全相同的。这个程序通过妙用ThreadLocalQ既实现多线Eƈ发,游兼数据的安全性?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;">四、ȝ</strong></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;"></strong> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal使用场合主要解决多线E中数据数据因ƈ发生不一致问题。ThreadLocal为每个线E的中ƈ发访问的数据提供一个副本,通过讉K副本来运行业务,q样的结果是耗费了内存,单大大减了U程同步所带来性能消耗,也减了U程q发控制的复杂度?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal不能使用原子cdQ只能用Objectcd。ThreadLocal的用比synchronized要简单得多?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">ThreadLocal和Synchonized都用于解军_U程q发讉K。但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机Ӟ使变量或代码块在某一时该只能被一个线E访问。而ThreadLocal为每一个线E都提供了变量的副本Q得每个线E在某一旉讉K到的q不是同一个对象,q样隔M多个U程Ҏ据的数据׃n。而Synchronized却正好相反,它用于在多个U程间通信时能够获得数据共享?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">Synchronized用于U程间的数据׃nQ而ThreadLocal则用于线E间的数据隔R?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">当然ThreadLocalq不能替代synchronized,它们处理不同的问题域。Synchronized用于实现同步机制Q比ThreadLocal更加复杂?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><strong style="padding: 0px; margin: 0px;">五、ThreadLocal使用的一般步?/strong></div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"> </div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">1、在多线E的c(如ThreadDemoc)中,创徏一个ThreadLocal对象threadXxxQ用来保存线E间需要隔d理的对象xxx?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">2、在ThreadDemocMQ创Z个获取要隔离讉K的数据的ҎgetXxx()Q在Ҏ中判断,若ThreadLocal对象为null时候,应该new()一个隔访问类型的对象Qƈ强制转换应用的类型?/div><div style="margin: 0px; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">3、在ThreadDemocȝrun()Ҏ中,通过getXxx()Ҏ获取要操作的数据Q这样可以保证每个线E对应一个数据对象,在Q何时刻都操作的是q个对象?/div><div></div><br /><br /><br /><br /><br /><br /></div><img src ="http://www.aygfsteel.com/jimingminlovefly/aggbug/422575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jimingminlovefly/" target="_blank">计明?/a> 2015-01-30 11:07 <a href="http://www.aygfsteel.com/jimingminlovefly/articles/422575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate-jpa-pdf.rarhttp://www.aygfsteel.com/jimingminlovefly/articles/378912.html计明?/dc:creator>计明?/author>Wed, 23 May 2012 02:07:00 GMThttp://www.aygfsteel.com/jimingminlovefly/articles/378912.htmlhttp://www.aygfsteel.com/jimingminlovefly/comments/378912.htmlhttp://www.aygfsteel.com/jimingminlovefly/articles/378912.html#Feedback0http://www.aygfsteel.com/jimingminlovefly/comments/commentRss/378912.htmlhttp://www.aygfsteel.com/jimingminlovefly/services/trackbacks/378912.htmlhibernate-jpa-pdf.rar

]]>
关于Hibernate?cascade ?inverse 的理?[转]http://www.aygfsteel.com/jimingminlovefly/articles/377508.html计明?/dc:creator>计明?/author>Mon, 07 May 2012 02:15:00 GMThttp://www.aygfsteel.com/jimingminlovefly/articles/377508.htmlhttp://www.aygfsteel.com/jimingminlovefly/comments/377508.htmlhttp://www.aygfsteel.com/jimingminlovefly/articles/377508.html#Feedback0http://www.aygfsteel.com/jimingminlovefly/comments/commentRss/377508.htmlhttp://www.aygfsteel.com/jimingminlovefly/services/trackbacks/377508.html

关于Hibernate?cascade ?inverse 的理解?/span>

您买的Hibernate书是哪一本呢Q?孙卫琴的_NHibernateQ还?深入出Hibernateq是那本。。?br />我是两本都买了,M来说q可以,但是Q有的地方讲的比较书面化Q比如inverseq属性?/span>

在学习Hibernate的过E中最不好理解的就是这两个属性了?br />(我当初学习Hibernate的时候,发现|上介绍q两个属性的文章倒是不少Q但是,居然有好多都是{帖。。。还有的是 照书搬~~-_-!!!)。。?/span>

据个例子Q书上说inverse=falseӞ׃控方l持关系。。?br />׃我也是初学者。。。再加上语文水^偏低。。。不理解“l持关系是啥意?#8221;囧~

提示Q?br />(1)如果Q您不了解Hibernate的one-to-many或many-to-one的概c?/span>

(2)如果Q你不了解Hibernate?#8220;自由?#8221;“持久?#8221;“游离?#8221;的概c?/span>

(3)如果Q您不了解Hibernate中的“脏数?#8221;的概c?/span>

(4)如果Q您对Hibernate中Session~存Q没有初步了解的话?br />(在Hibernate中调用saveq行存储数据的时?q不是马上就Ҏ据库q行insert操作Q而是会将?#8220;数据对象(vo)”U_Hibernate的Session~存?

在上面的4条提CZQ如果您对其中的某一条,不是很清楚的话。希望请先了解有关知识?br />否则Q可能您?“无法或很?#8221;理解 cascade ?inverse q?个属性?/span>

首相Qcascade ?inverse q两个属性,其实是完全不同的两个东西Q想要了解他们各自的“用途与区别”Q详见如下介l:

q里有两个表:

Q?Qclass   (班?
相应字段Q?br />cid    varchar(32) 主键 not-null (班id)
cname varchar(16)      not-null (班名称)  

Q?Qstudent (学生?
相应字段Q?br />sid    varchar(32) 主键 not-null (学生id)
sname varchar(16)      not-null (学生姓名)
class_id varchar(32)   not-null (学生所属班U?

一个班U?class)对应多个学生(student)Q所以班U表(class)是“one-to-many”?br />反之student是many-to-one

//--------Classcȝ代码--------
public class Class implements.....
{
private cId = "";
private cName = "";
private students = java.util.HashMap();
// 省略对应?geter setter
}
//--------Class.hbm.xml--------
<hibernate-mapping>
<class name="lcx.vo.Class" table="class"
   catalog="demo">
   <id name="cid" type="java.lang.String">
    <column name="cid" length="32" />
    <generator class="uuid.hex" />
   </id>
   <property name="name" type="java.lang.String">
    <column name="cname" length="16" not-null="true" />
   </property>
  
   <set name="students" table="student" cascade="save-update">
    <key column="class" />
    <one-to-many class="lcx.vo.Student" />
   </set>
</class>
</hibernate-mapping>

//--------Studentcȝ代码;*******
public class Student implements.....
{
private sId = "";
private sName = "";
private Class class = null;
// 省略对应?geter setter
}
// Student.hbm.xml
<hibernate-mapping>
<class name="lcx.vo.Student" table="student" catalog="demo">
   <id name="cid" type="java.lang.String">
    <column name="sid" length="32" />
    <generator class="uuid.hex" />
   </id>
   <many-to-one name="class"
    class="lcx.vo.Class"
    column="class_id"
    not-null="true"
   />   
</class>
</hibernate-mapping>

Q一Q?cascade 的介l:
当Hibernate持久化一?#8220;临时对象(也叫自由态对?”Ӟ在默认的情况?卻I没有讄cascade属性或cascade=none?QHibernate不会自动“持久化他所兌”的其他时对象?/span>

其中几种最常用的联ؓ
1,all:所有操作都传递到子实?
-保存,更新,删除.
2,sav-update:保存和更?
3,delete:删除.
4,delete-orphan:所有操作都传递到子实?q删除不再与对象兌的对?
hibernate不将U联传递到数据库它只在内部理U联

上面q些话是什么意思呢Q?什么叫不会自动 “持久?#8221;兌的时对象呢Q?/span>

看如下代码:

// 创徏一?临时对象(也叫自由态对?
// 也就是说q个 class 没有被HibernateU_Session~存理?br />Class class = new Class();
//class.id 动生?br />class.setName("一q1?);

Student stu = new Student();
//student.id 动生?br />stu.setName("白?);
stu.setClass(class);

// 关键是q里。。?br />class.getStudents().add(stu);

session.save(class);
// 提交

// 注意: Class.hbm.xml文g?cascade="save-update"q且也没有设|inverse属?也就是说inverse=false;
// 此时如果你开启了Hibernate的显CHQL语句功能Q那么控制台会昄如下3条HQLQ?/span>

//----------------------------------------********
insert into demo.class (cid, cname) values (66666666666666666666666666666666, 一q1?
insert into demo.student (sid,sname,class_id) values (8888888888888888811cb2e04c888888, 白? 66666666666666666666666666666666)
update demo.student set class_id=66666666666666666666666666666666 where sid=8888888888888888811cb2e04c888888
//----------------------------------------********

那么Z么会出现Q这3条HQL语句呢,我们来一一分析一下:

W?条HQL语句:
其实W一条HQL比较好理解,
当我们调?session.save(class) 后,在Hibernateq行提交的时候,
会发?#8220;?#8221;一?#8220;?#8221;的数据要插入(insert)Q所以就往class表中,插入了这条新的class记录?/span>

W?条HQL语句Q?br />注意问题在q里Q?br />q里Z么又出现了一条insert语句呢?而且q是向student表中插入数据?br />我们在上面的代码中,q没有编写类?#8220;session.save(student)”q样的语句啊?br />q是Z么呢Q?br />其实原因Q是q么回事Q因为我们在class端,讄?U联更新"(?cascade="save-update")Q?br />也就是说Q当Hibernate在向class表中插入“?#8221;对象记录Ӟ会检?#8220;Class对象”所兌的属?是<set>对应的属?Q是否发生过变化Q如果发生了变化Q就按照“U联属?cascade)”所讑֮的内?br />q行操作?/span>

上面讲的q句话到底是什么意思呢Q?br />用你?#8220;?#8221;话说Q就是:
因ؓ调用?class.getStudents().add(stu);
所以,在Hibernate在进行插?class对象的时候,发现class对象Q所兌的集合中Q有一?br />“自由?#8221;的对象,而又因ؓclass端设|了“U联属性cascade”Q所以,在插入这?“新class对象”Ӟ也一同把他内部的那些Q还属于“自由?#8221;的其他对象,也一同插入到Q他们所对应的表中去了?/span>

q是不明白的话。。。可以看看。孙卫琴的《精通Hibernate》,在书上的W?49|?br />但是关于inverse的介l。。。写的就有些书面化了Q如果语文不好的话。。。就难懂咯~

W?条HQL语句Q?br />W三条HQL语句是一条update语句Q是不是觉得Q很莫名其妙。。。?br />Hibernate大脑q水了吧Q怎么吃饱了撑得,重复更新记录啊啊啊啊?br />假如Q我们把 class端的配置文档中的 invser属性设|ؓtrue(卻Iinverse=true)
在执行上面的E序Q发玎ͼ变?条insert语句啦。。。。?update没啦。。?
看来W三条的update语句和inverse有着密切的关p(他两有一腿~Q?/span>

所以我们下边,来介绍一下inverse属?

当调?Class.getStudents().add(stu)ҎQ进行添加操作时Q?
(卻I?"q个Class对象"所属的“集合 (也就是调用getStudentsҎ所q回的那个Set集合)”中添加一个Student(?add(stu))Q也是_q个“?#8221;d的Student对象(stu)Q?
他的Student.class_id字段“必须”Q要{于“被添加方Class”的主??Class.cid)?
?#8220;数据?#8221;层面来讲Q也是_q个“?#8221;d?#8220;Student”的class_id字段Q必要?#8220;Class”的cid字段Q存?d键关??

正因为如此:所以Hibernate“?#8221; 在进?"Class.getStudents().add(stu)" q样的操作时Q?
出现意外情况(? stu.getClass=nullQ即Qstu没有所属班U?Q?br />?#8220;d?#8221;(Student)?#8220;被添加方”(Class)Q存?#8220;外键”不一致的情况发生?
所以就出现?那条多余的update语句。即Qone-to-manyQClass端)dȝ护Child.Class_id
所以就是说QHibernate怕出错,q你多执行一ơ无用的更新语句Q以保证 add ?Class“集合”中的所有Student
都是要与Class有外键关联的?/span>

用普通话说就?
一q??getStudents().add(白?;
一q??getStudents().add(大白?;

也就是说现在不管?白?q是 大白?
如果他们Q目前还没有自己的班U的话,
一q?班的班主d会主动邀请他们成Zq?班的同学啦~?/span>

也就是说 一q?班的班主?d邀?同学Q而不?同学自己来~~~ 所以效率也降低了。。。?/span>

所以我们一般把 一对多?invser讄为trueQ即Q不让主控端ȝ护主键关联,
Q即Q让同学自己L班Q?br />说白了,是Qone-to-many端不用去理 “新添加对?#8221; 的主外键U束问题?/span>

把one-to-many端(?class?的invser讄为true
(卻I每次向class.getStudentsq个集合中添?studentӞ不去dupdate对应的外?Q?br />而是在student端去手动讄
例如Q?br />student.setClass(class);
session.save(student);
q样手动讄 student与class兌啦。。。?br />所以上面的E序“最?#8221;q是写成q样Q?/span>

Class class = new Class();
class.setName("一q1?);
session.save(class);

Student stu = new Student();
stu.setName("白?);
stu.setClass(class);
session.save(class);

/*
此时向class集合add内容Q不会进行数据库操作(update)?br />“更新”的只是session~存中,数据镜像?br />q样做的好处是:不仅减少了update语句Q?br />而且Q同时也更新了session~存?br />------------------------
而在原来:
one-to-many端inverse=falseӞ虽然也更新seesion~存中的class集合Q?br />但是有却又多余update
*/
class.getStudents().add(stu);
// 提交

ȝ:
当inverse=false q且向one-to-many端的兌集合Q添?#8220;新对?? 自由态对?” Ӟ
Hibernate׃自动Q去update?#8220;个刚刚到来的” “自由态对?#8221;的外键?br />Q如果你向,one-to-many端添的集合中Qadd一?#8220;已经持久化了的对?#8221;Q那׃会出现update?因ؓ已经持久化过?Q除非,你去 更改“那个持久化对?#8221;所对应的外键。。。那L话。。。呵呵呵~~~
你可以试一试,应该不会报错Q你可以当做l习d一下,加深cascade和inverseq两个属性的理解Q?/span>


// 如果看懂了上面的内容。来看一下,下面的东ѝ?br />假如Q将one-to-many??Class??hbm.xml 文档中的cascadeU除?或把cascade="none"?br />那么上面的代码会出现什么情况呢?br />l果会出?条HQLQ和一堆Exception

insert into demo.class (cid, cname) values (66666666666666666666666666666666, 一q1?
update demo.student set class_id=66666666666666666666666666666666 where sid=8888888888888888811cb2e04c888888
Hibernate Exceptinon......................................

相比较cascade被设|?save-update"的时候,~少??insert语句Q而且也多了一些Exception?/span>

那么Q到底是了?条insert语句呢?
是q条Q?br />insert into demo.student (sid,sname,class_id) values (8888888888888888811cb2e04c888888, 白? 66666666666666666666666666666666)

之所以会出现Q这L现象Q想必您已经早就看出来了?br />因ؓQ我没有讄Class端的CascadeQ所以在save(class)的时候,q没有自动将其所兌?#8220;自由态对?#8221;q行持久化操作?br />然而,又因?Class端的inverse=falseQ所以,Class会自动去l持Q那?“新来的student” 的外键?br />所以会出现Q没有insertpupdate啦。。。?br />然后在就是Exception?/span>

?

]]>
MyEclipse从数据库反向生成实体cMHibernate方式 反向工程http://www.aygfsteel.com/jimingminlovefly/articles/367169.html计明?/dc:creator>计明?/author>Mon, 26 Dec 2011 03:34:00 GMThttp://www.aygfsteel.com/jimingminlovefly/articles/367169.htmlhttp://www.aygfsteel.com/jimingminlovefly/comments/367169.htmlhttp://www.aygfsteel.com/jimingminlovefly/articles/367169.html#Feedback0http://www.aygfsteel.com/jimingminlovefly/comments/commentRss/367169.htmlhttp://www.aygfsteel.com/jimingminlovefly/services/trackbacks/367169.htmlhttp://blog.csdn.net/rockstar541/article/details/6840114

]]>
վ֩ģ壺 ˮ| | | | ӳ| ɽ| | | ʡ| | | | | Ϊ| | | | | | ƽ| گ| ¡Ң| Դ| | | | | Դ| | | ̨| | | | »Ȱ| ƽң| ɽ| ֵ| | ±| ƾ|