This article takes the database operation DAO as an example to describe the use of threadlocal, the following is a counter example:
Package Com.daxin.threadlocal.dao;import Java.sql.connection;import Java.sql.sqlexception;import Java.sql.statement;public class Userdaoerrordemo {//① a non-thread-safe variable private Connection conn;/** * AddUser the commit of a transaction is prone to confusion when concurrency occurs */public void AddUser () {try {//② reference non-thread safe variable conn.setautocommit (false); Statement stat = conn.createstatement (); Stat.executequery ("SQL"); Conn.commit ();} catch (SQLException e) {e.printstacktrace (); try {conn.rollback ();} catch (SQLException E1) {e1.printstacktrace ();}}}}
There is a thread-safety problem that can occur when multiple threads commit a transaction. Therefore, the following scenarios can be adopted:
Package Com.daxin.threadlocal.dao;import Java.sql.connection;import Java.sql.drivermanager;import Java.sql.sqlexception;import java.sql.statement;/** * Analog Database Connection Manager * * @author liuguangxin * */class ConnectionManager {STA Tic string drivername = "", static string url = "", static string user = "", static string password = "";p ublic static Connec tion getconnection () {try {return drivermanager.getconnection (URL, user, password);} catch (SQLException e) {//TODO auto- Generated catch Blocke.printstacktrace ();} return null;}} /** * * @author liuguangxin * */public class Userdao {//① use threadlocal to save connection variable//Because DAO pass-through is just a singleton in the system, so it can be shared by multiple threads, so the CO Nnthreadlocal is also shared by multiple threads. Private threadlocal<connection> connthreadlocal = new threadlocal<connection> ();p ublic Connection Getconnection () {//② If connthreadlocal does not have a connection corresponding to this thread to create a new connection and save it to a thread-local variable. if (connthreadlocal.get () = = null) {Connection conn = connectionmanager.getconnection (); Connthreadlocal.set (conn); Return conn;} else {//③ directly returns the thread local variable return connthreadlocal.get ();}} public void AddUser (string userName, String passWord) {Connection conn = getconnection (); Statement stmt = null;try {Conn.setautocommit (false); stmt = Conn.createstatement ();//Pseudo-code stmt.executequery ("insert Into user ... "); Conn.commit ();} catch (SQLException e) {e.printstacktrace (); try {conn.rollback ();} catch (SQLException ex) {ex.printstacktrace ();}} finally {if (stmt! = null) {try {stmt.close ()} catch (SQLException e) {e.printstacktrace ()}}}}
Use cases for Java threadlocal