serverlet线程安全吗

本文探讨了Servlet的线程安全问题,通过一个示例展示了如何使用同步机制解决线程安全问题,并强调了全局变量和静态变量是导致线程不安全的主要原因。
本文属于转载:http://www.cnblogs.com/itTeacher/archive/2012/11/14/2769822.html

这个问题,在网上没有看到一个确切的答案,所以我们来分析一下:
首先什么是线程安全?
引用概念:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

那么我们都知道servlet是多线程的,同时一个servlet实现类只会有一个实例对象,也就是它是Singleton的,所以多个线程是可能会访问同一个servlet实例对象的。

每个线程都会为数据实例对象开辟单独的引用,那么servlet会是线程安全的吗?

要判断是否是线程安全,我们需要知道线程安全问题是由什么引起的。
搜索得到答案:线程安全问题都是由全局变量及静态变量引起的。
看到这个答案,突然想起很多年前调查过的一个bug, 那时我们系统中遗留的代码中写了很多全局变量,有一次发布后,客户反馈,当有多人同时进行某个操作时,我们的数据出了问题,那时我们调查后的结果就是:多人同步操作时,有些全局变量的值不对了,之后我们专门设一个人花了很多工夫来将所有全局变量都改成了局部变量了,并且项目要求以后不允许用全局变量。原来那时侯我就已经碰到过线程不安全的情况了啊,不过处理方式或者不用全局,或者加入同步,若加入同步同时也要考虑一下对程序效率会不会产生影响。

由此可知,servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之,就是线程安全的。

在网上找到一个例子,如下:

public class TestServlet extends HttpServlet {
     private int count = 0;  
      
     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>");
         for(int i=0;i<5;i++){
             response.getWriter().println("count = " + count + "<BR>");
             try {
                 Thread.sleep(1000);  
                 count++;  
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }



当同时打开多个浏览器,输入http://localhost:8080/ServletTest/TestServlet时,他们显示的结果不同,这就说明了对于属性count来说,它是线程不安全的,
为了解决这个问题,将代码重构,如下:

public class TestServlet extends HttpServlet {
      private int count = 0;  
      private String synchronizeStr = "";
      @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>");
         synchronized (synchronizeStr){
             for(int i=0;i<5;i++){
                 response.getWriter().println("count = " + count + "<BR>");
                 try {
                     Thread.sleep(1000);  
                     count++;  
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }
Lab 2 Chapter 1 Java Language Programming Chapter 1: Variables and Primitive Data Types (Part 2) Instructor: Ahsan Shehzad Date: September 3, 2025 Practical Session Objective Lab Goal: Store and Display a Contact Our objective is to create a simple Java program that stores the information for one contact using variables and then prints that information neatly to the console. Final Result Preview: (This is what your console output will look like) (Screenshot of the final console output will go here) Prerequisites: Java Development Kit (JDK) 11 or higher installed. An IDE like IntelliJ IDEA Community Edition ready to go. Step-by-Step Guided Exercise Step 1: Create the Project Structure Goal: Set up your project in IntelliJ and create the main class file. Instructions: 1. Open IntelliJ IDEA. 2. Go to File > New > Project... . 3. Name your project MyContactManager and choose a location to save it. Contact Profile: Name: John Doe Age: 32 Phone: 447700900123 Is a Friend: true 1 2 3 4 54. Ensure Java is selected and you have a JDK configured. 5. Once the project is created, right-click the src folder in the Project Explorer. 6. Select New > Java Class . 7. Name the class Main and press Enter. Code Block: Your IDE will generate this boilerplate code for you. Add the main method inside the class. Expected Result: You have a clean Main.java file, and the program can be run (though it won't do anything yet). Step 2: Declare and Initialize Contact Variables Goal: Create variables inside the main method to hold a contact's data. Instructions: 1. Inside the main method, declare and initialize variables for each piece of contact information. 2. Choose the most appropriate data type for each value. 3. Pay special attention to the literals for long ( L ) and String (double quotes). Code Block: Add the following lines inside your main method. Expected Result: The program should compile without any errors. When you run it, still nothing will happen, but the data is now stored in memory. public class Main { public static void main(String[] args) { // Our code will go here! } } 1 2 3 4 5 public static void main(String[] args) { // String is a special object type we use for text. String firstName = "John"; String lastName = "Doe"; // Use 'int' for age. int age = 32; // A phone number can be large, so 'long' is a safe choice. long phoneNumber = 447700900123L; // 'boolean' is perfect for a simple true/false status. boolean isFriend = true; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14Step 3: Display the Information Goal: Use System.out.println() and string concatenation ( + ) to print the stored data to the console. Instructions: 1. After the variable declarations, add a println statement to act as a header. 2. For each variable, write a println that combines a descriptive label (e.g., "Name: ") with the variable itself using the + operator. Code Block: Add these lines after your variables in the main method. Expected Result: When you run the main method, you should see the formatted contact details printed to your console, matching the goal on slide 13. Putting It All Together Goal: Review the complete, final code for this lab session. Instructions: Your final Main.java file should look exactly like this. Make sure your code matches and run it one last time to confirm the output. Code Block: // ... variables from previous slide ... // --- Displaying the Information --- System.out.println("Contact Profile:"); System.out.println("Name: " + firstName + " " + lastName); System.out.println("Age: " + age); System.out.println("Phone: " + phoneNumber); System.out.println("Is a Friend: " + isFriend); 1 2 3 4 5 6 7 8 public class Main { public static void main(String[] args) { // --- Storing Contact Information --- // String is a special object type we use for text. String firstName = "John"; String lastName = "Doe"; // Use 'int' for age. int age = 32; // A phone number can be large, so 'long' is a safe choice. long phoneNumber = 447700900123L; // 'boolean' is perfect for a simple true/false status. boolean isFriend = true; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16Expected Result: A clean, working program that successfully stores and displays data. You've just completed Phase 1 of the project! (This slide is intentionally left blank to fit the 21-slide structure. It can be used for instructor-specific notes or an extra exercise if needed.) Challenge Task For Those Who Finish Early... Challenge 1: Add a Second Contact Declare and initialize a new set of variables for a second person (e.g., firstName2 , age2 , etc.). Print their details to the console, separated from the first contact by a line of dashes ( "----------" ). Challenge 2: Perform a Calculation After creating both contacts, declare a new double variable named averageAge . Calculate the average age of the two contacts and store it in the variable. Hint: (age1 + age2) / 2.0 . Why / 2.0 and not / 2 ? Print the average age to the console with a descriptive label. // --- Displaying the Information --- System.out.println("Contact Profile:"); System.out.println("Name: " + firstName + " " + lastName); System.out.println("Age: " + age); System.out.println("Phone: " + phoneNumber); System.out.println("Is a Friend: " + isFriend); } } 17 18 19 20 21 22 23 24 答案是什么
最新发布
09-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值