`

ThreadLocal 我所用到的地方

阅读更多

92.  现在来看怎么把三个方法保证同步,servlet是单实例多线程运行的,你去调用FlowCardServlet就
会启动一个线程,在这个线程里其实就调用了你写的那三个方法,现在我就只要保证你这三个方法都在一个线程里面就可以了。

93.  在同一个线程里保证使用一个connection这就涉及到一个类ThreadLocal
这个类不是本地线程的意思,这个类就在java.lang包中。作用:你放在这里面的东西,他会在整个线程里共享,在其它线程里不共享。


94.  不用框架要考虑的东西太多了,这样就会造成以后的维护成本提高啊。


95.  你可以这样理解,这个类的底层是 一个map{
key=当前线程变量001,也可以理解为这个是一个唯一标识的东西吧,不好理解,你就这么理解
value = new connection()

key=当前线程变量002
value = new connection()  这两个connection是不一样的,他们是不相互干扰的。
}

在这整个线程中就共享着一个
value对应的就是你具体的东西,你爱放什么就放什么,他接收一个Object参数。


96.  ThreadLocal这个很重要,因为现在很多都使用这个东西。
这个类里面就四个方法。
public void set(T value){}你传一个connection进来,他就放到了一个map里面去了。

public void set(T value){
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map != null)
    map.set(this,value);
else
    createMap(t,value);
}别人再调用,他又map.set()设置一个了。如果有10个人设置进去东西了,我怎么就能拿到我的呢?


97.  他还有一个get(T value)方法。
map.get(0001);你当前线程对应的是0001  他就拿0001的东西。


98.  现在再建一个类来封装ThreadLocal
他命名命得好啊,connection的管理
public class ConnectionManager{
private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();

现在都是在多线程中运行的,你开一个就开一个线程我得看看,在当前线程中绑没绑定一个connection
public static Connection getConnection(){
Connection conn = connectionHolder.get();
用了泛型你不用管了,里面就是coneciton
if(conn == null){ 当前线程没有绑定我就创建
JdbcInfo jdbcInfo = ConfigReader.getInstance().getJdbcInfo();
Class.forName(jdbcInfo.getDriverName());
conn = DriverManager.getConneciton(jdbcInfo.getUrl(),jdbcInfo.getUsername(),jdbcInfo.getPassword());
connectionHolder.set(conn);
}
}
return conn;
}

holder:持有

关闭方法,你想你要关闭,你怎么关,你只能关你自己的connection
public static void closeConnection(){
Connection conn = connectionHolder.get();
if(conn !=null){
    conn.close();
conntionHolder.remove();你把他关了,他map里面的东西还存在啊,所以你得移除了。
}
}


99.  这思想就和我在方法中定义的变量只能在这个方法里面使用。


100.  我们还可以采用同步机制来解决线程安全问题

 

 

1.  connection什么时候关闭,应该是那三个方法全部执行完


2.  这个connection应该是在FlowCardServiceImpl这一层开,在这一层关。

 

 

 

/**
 * 采用ThreadLocal封装Connection
 * ThreadLocal可以在同一个线程中共享变量
 * @author Administrator
 *
 */
public class ConnectionManager {

    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();
   
    /**
     * 取得connection
     * @return
     */
    public static Connection getConnection() {
        Connection conn = connectionHolder.get();
        //如果在ThreadLocal中不存在与当前线程绑定的Connection
        //那么我们就创建一个Connection,并将其放到ThreadLocal中
        if (conn == null) {
            try {
                //取得jdbc配置信息
                JdbcInfo jdbcInfo = ConfigReader.getInstance().getJdbcInfo();
                Class.forName(jdbcInfo.getDriverName());
                conn = DriverManager.getConnection(jdbcInfo.getUrl(), jdbcInfo.getUsername(), jdbcInfo.getPassword());
               
                //放到ThreadLocal中
                connectionHolder.set(conn);
            } catch (ClassNotFoundException e) {
                //记录日志可以将类不能找记录进去,这样可以更准确的定位问题
                //但是给用户不应该抛出类不能找到,应该抛出用户能够理解的错误
                e.printStackTrace();
                throw new AppException("系统出现故障,请联系系统管理员!");
            } catch (SQLException e) {
                e.printStackTrace();
                throw new AppException("系统出现故障,请联系系统管理员!");
            }
        }
        return conn;
    }
   
    /**
     * 关于connection
     */
    public static void closeConnection() {
        Connection conn = connectionHolder.get();
        if (conn != null) {
            try {
                conn.close();
                //从ThreadLocal中移除
                connectionHolder.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
       
    }
   
    public static void close(PreparedStatement pstmt) {
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void close(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void commit(Connection conn) {
        if (conn != null) {
            try {
                conn.commit();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void rollback(Connection conn) {
        if (conn != null) {
            try {
                conn.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void setAutoCommit(Connection conn, boolean autoCommit) {
        if (conn != null) {
            try {
                conn.setAutoCommit(autoCommit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
   
    public static void close(Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }   
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics