`
newleague
  • 浏览: 1499786 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

Servlet和ThreadLocal的测试

阅读更多

正确理解ThreadLocal http://www.iteye.com/topic/103804

总之,ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点:
1。每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
2。将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。

 

一个TheadLocal实例

下面,我们通过一个具体的实例了解一下ThreadLocal的具体使用方法。

代码清单2 SequenceNumber

package com.baobaotao.basic;

public class SequenceNumber {

①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值

private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>(){

public Integer initialValue(){

return 0;

}

};

②获取下一个序列值

public int getNextNum(){

seqNum.set(seqNum.get()+1);

return seqNum.get();

}

public static void main(String[] args)

{

SequenceNumber sn = new SequenceNumber();

③ 3个线程共享sn,各自产生序列号

TestClient t1 = new TestClient(sn);

TestClient t2 = new TestClient(sn);

TestClient t3 = new TestClient(sn);

t1.start();

t2.start();

t3.start();

}

private static class TestClient extends Thread

{

private SequenceNumber sn;

public TestClient(SequenceNumber sn) {

this.sn = sn;

}

public void run()

{

for (int i = 0; i < 3; i++) {④每个线程打出3个序列值

System.out.println("thread["+Thread.currentThread().getName()+

"] sn["+sn.getNextNum()+"]");

}

}

}

}

 

通常我们通过匿名内部类的方式定义ThreadLocal的子类,提供初始的变量值,如例子中①处所示。TestClient线程产生一组序列号,在③处,我们生成3个TestClient,它们共享同一个SequenceNumber实例。运行以上代码,在控制台上输出以下的结果:

thread[Thread-2] sn[1]

thread[Thread-0] sn[1]

thread[Thread-1] sn[1]

thread[Thread-2] sn[2]

thread[Thread-0] sn[2]

thread[Thread-1] sn[2]

thread[Thread-2] sn[3]

thread[Thread-0] sn[3]

thread[Thread-1] sn[3]

考察输出的结果信息,我们发现每个线程所产生的序号虽然都共享同一个SequenceNumber实例,但它们并没有发生相互干扰的情况,而是各自产生独立的序列号,这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。

 

 http://blog.csdn.net/qjyong/archive/2008/03/08/2158097.aspx

 

(madp把ThreadLocal看作Map)

 

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
 public class TestThreadServlet extends HttpServlet {
        private static ThreadLocal thread = new ThreadLocal();

        private int flag = 0;
       
  public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
   flag++;
   String str = "This is the first String." + new Object();
   if (thread.get() == null)
   thread.set(str);
   PrintWriter out = response.getWriter();
   out.println("<p>");
   out.println("<BR>flag : " + flag);
   out.println("<BR>sessionid : " + request.getSession().getId());
   out.println("<BR>servlet : " + this.toString());
   out.println("<BR>thread : " + thread.get());
   out.println("</p>");
  }
   }

 


  执行结果:
  
  Session 1:
  
  flag : 2
  sessionid : amGeaiVwKvL9
  servlet : test.other.TestThreadServlet@5f2db0
  thread : This is the first String.Java.lang.Object@1ad6b4b
  
  Session 1:
  
  flag : 3
  sessionid : aR3GkcUQoXT-
  servlet : test.other.TestThreadServlet@5f2db0
  thread : This is the first String.java.lang.Object@6214f5
  
  由执行结果可以看出
  
  1 服务器对每个Servlet只创建一个实例。flag不停增加
  
  2 Session范围内的ThreadLocal中对象唯一。不同的请求,Object的hashCode相同。
  
  3 不同的Session共享ThreadLocal,但内部对象不同
  
  另:后来有人提醒我,实际上在web.XML为同一个servlet配置不同的名字,将会是两个不同的实例。也就是说,servlet的实例与配置有关。
分享到:
评论

相关推荐

    servlet 模拟

    通过模拟Servlet,你可以创建一个简单的Servlet类并故意引入线程不安全的代码,然后通过并发测试来观察并修复这些问题。这将帮助你更好地理解Servlet的线程模型以及如何编写线程安全的代码。 在实践过程中,可以...

    Servlet原理大大大大大大大大大大大大大大大大大大大

    在"ServletTest02"这个文件中,可能包含了Servlet的测试代码或者示例,用于演示如何创建和配置Servlet,以及如何处理HTTP请求。可能涉及到web.xml配置文件,其中定义了Servlet的映射路径、初始化参数等。此外,可能...

    深入研究Servlet线程安全性问题

    在并发测试中,通过人为引入延时,更容易暴露这个问题:用户a和b的请求可能会交错,使得用户b看到的是用户a的信息,而用户a则可能看不到任何输出。 Java内存模型(JMM)进一步解释了这种问题的根源。JMM规定,实例...

    ikm_java_8.pdf

    private static final ThreadLocal&lt;Integer&gt; threadLocal = new ThreadLocal(); public static void main(String[] args) { threadLocal.set(10); // 在当前线程设置值 // 创建新线程并设置不同的值 Thread...

    东软 校园招聘考试套题 嵌入式 Java C++

    8. 测试:掌握JUnit和Mockito等测试工具,理解单元测试和集成测试的重要性。 【C++编程】 C++作为底层开发和高性能计算的重要语言,也是东软招聘的考察点: 1. C++基础:理解C++的三大特性:面向过程、面向对象和...

    JAVA项目开发全程实录.(ED2000.COM).rar

    9. **Maven或Gradle构建工具**:这些工具能够自动化构建、测试和部署过程,简化项目的管理。了解其配置和使用方法,是现代Java开发的必备技能。 10. **单元测试与集成测试**:JUnit是Java中常用的单元测试框架,而...

    Tomcat中一种半通用回显方法 - 先知社区1

    作者发现`org.apache.catalina.core.ApplicationFilterChain`类中有一个`lastServicedRequest`和`lastServicedResponse`的ThreadLocal变量,可以存储当前线程的请求和响应对象。 3. **反射修改`...

    j2ee的aop方式记录日志

    - 在Filter或者Servlet初始化时,将用户和请求信息存入ThreadLocal。 - 在日志切面中,可以直接从ThreadLocal中获取这些信息,添加到日志中。 3. **配置Spring** - 将切面类加入到Spring容器中,如果是XML配置,...

    struts2中action如何获取jsp页面参数1.pdf

    - 在Action中,优先考虑使用ActionContext,因为它已经足够满足大部分需求,避免直接操作Servlet相关对象,使得Action与Servlet层解耦,提高代码的可维护性和可测试性。 - 如果ActionContext不能满足需求(例如,...

    基于web的网上选课系统的开题报告.pdf

    同时,系统组件化的设计可以使得各个部分可以独立开发、测试和更新,如Filter、Action、Service、DAO(数据访问对象)等。 10. 线程局部变量(ThreadLocal) 报告提到ThreadLocal,这是Java中一个用于创建线程局部...

    学习java必看的东西

    8. **单元测试与持续集成**:一个成熟的开源项目会有完善的测试体系,如JUnit和Mockito等测试工具的使用,以及持续集成(如Jenkins)的配置。 9. **国际化与本地化**:大型应用往往需要支持多语言环境,jive的国际...

    基于全局储存的新思路 _ Tomcat的一种通用回显方法研究1

    通过这种方式,即使在各种框架和版本的封装下,也能找到一种相对通用的方法来获取和回显Request及Response,这对于进行安全测试和漏洞挖掘具有重要意义。 在实际应用中,这种方法可以帮助安全研究人员绕过框架的...

    计算机专业毕业论文题目_大全.docx

    - MVC(Model-View-Controller)架构:理解和应用MVC设计模式,提高代码可维护性和测试性。 - Razor视图引擎:学习如何编写Razor语法,创建高效简洁的视图模板。 - WebAPI和RESTful服务:构建HTTP服务,实现客户端与...

    java学习课件

    课件会教授如何创建和管理线程,理解线程同步和互斥的概念,如synchronized关键字、wait()、notify()和notifyAll()方法,以及使用ThreadLocal和ExecutorService管理线程池。 7. **反射与注解**:Java反射允许在运行...

    java面试题

    - **Struts 1.2**:Action类依赖Servlet API,导致测试时需要模拟容器环境。 - **Struts 2.0**:Action类不直接依赖Servlet API,增强了可测试性。 4. **可测试性**: - **Struts 1.2**:测试较为复杂,因为...

    Struts+Hibernate+Spring常见面试题

    另外,可以通过实现`ActionSupport`的`validate()`方法进行请求级别的数据校验,或者使用基于拦截器的线程绑定解决方案,如Spring的`ThreadLocal`。 【Hibernate】 Hibernate是一个对象关系映射(ORM)框架,用于...

    java项目集合(强)

    9. **测试**:JUnit,Mockito等单元测试工具的使用,以及集成测试和性能测试的基本概念。 10. **持续集成/持续部署**:Git版本控制,Jenkins,Docker,Kubernetes等工具在项目构建和部署中的应用。 11. **分布式**...

    浙江大学Java应用技术资料.7z

    14. **测试技术**:包括单元测试(JUnit)和集成测试(TestNG),以及Mockito等模拟框架的使用。 15. **项目实战**:可能包含实际的项目案例,如Web应用开发、数据分析或移动服务端开发,提供实践经验。 这些知识...

Global site tag (gtag.js) - Google Analytics