ThreadLocal类

来源:互联网 发布:汉字笔顺软件 编辑:程序博客网 时间:2024/05/16 13:00

      通常在多线程中,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本

      实现线程本地类其实不难:以当前线程为key,要保存的对象为value

      public class ThreadLocalSample {

           private Map map = Collections.synchronizedMap(new HashMap());

          

           public void set(Object value) {

               map.put(Thread.currentThread(), value);

           }

 

           public Object get() {

               Object value = map.get(Thread.currentThread());

               return value;

           }

      }

      ThreadLocal可用在Servlet的过滤器中,比如:每一个请求都由一个Connection来操作数据库,由于Servlet只有一个实例,所以应该是每个线程用一个连接,而不是所有线程用一个Connection,因此需要用到ThreadLocal类;由于Servlet是在Filter链的调用中点执行,即Filter1->Filter2->...->Servlet->Filter2->Filter1,因此:可以用一个Filter,在这个Filter调用下一个Filter前初始化连接,并将其放入ThreadLocal中,在调用又回到这个Filter时,得到连接并关闭。

      代码如下:

      public class TransactionManageFilter implements Filter {

              private FilterConfig config;

 

              public void init(FilterConfig config) throws ServletException {
                  this.config = config;

              }

 

              public void destroy() {
                 config = null;
              }

             
               public void doFilter(ServletRequest request, ServletResponse response,
                                              FilterChain chain) throws IOException, ServletException {

                      Connection conn = ConnectionManager.currentConnection();

                      try {

                            conn.setAutoCommit(false);

                            chain.doFilter(request, response, chain);

                            conn.commit();

                      } catch (Exception e) {

                            conn.rollback();

                      } finally {

                            try {

                               conn.setAutoCommit(true);

                               conn.close();

                               ConnectionManager.removeConnection();

                            } catch (Exception e) {}

                      }

               }

      }

 

      public class ConnectionManager {

          private static ThreadLocal currConn = new ThreadLocal();

      

          public static Connection currentConnection() {

              Object obj = currConn.get();

              if (obj != null) {

                 return (Connection)obj;

              } else {

                  Connection conn = ConnectionFactory.getConnection();

                  currConn.set(conn);

                  return conn;

              }

          }

 

         public static void removeConnection() {

             Object obj = currConn.get();

             if (obj != null) {

                currConn.set(null);

             }

        }

     }