如何用Synchronied解决Servlet多线程安全问题?

2021-07-08 14:29:53 浏览数 (1)

1.用Synchronied解决多线程安全问题:

马克-to-win:我们先铺垫Servlet的多线程基础知识。到现在为止,我们所接触到的Servlet都是这样的:第一个人访问Servlet的时候,Servlet会被实例化。之后的人再访问这个Servlet的时候,这个Servlet就不再被实例化了,而是采取线程的模式。用每一个由这个servlet而来的线程来应答来请求的客户。这样的话,Servlet的实例变量,实际上是被所有客户的线程共享的。这样就会出现线程安全的问题。一谈到多线程安全,就需要谈到我"Java初级"部分第六章的那个多线程安全的例子。这里基本还是用那个例子,只不过是放在Servlet环境下。那里对Critical data(关键数据[多个线程同时会修改的数据])的解决方案,就是在访问Critical data的方法前面加上关键字Synchronized。这里建议的解决方案也是这样。马克-to-win:我们先看一个没有加Synchonized的 critical data的例子。见下面例:2.1.1,还是像"Java初级"部分第六章那里一样,onlySellOne对于一个人来讲,一次只能卖一本书。对于本例来讲,我们用一个浏览器模拟一个人。观察浏览器,我们发现,对于有的人(http-8080-Processor25)来讲,开始还是18本书,买了一本书之后(调用一次onlySellOne),自己一看,还剩下16本书。这里显然出现了问题。问题就在于,有其他人同时也在买书。关键数据(bookNum)可以被多个线程同时修改。对于例:2.1.2,我们通过在onlySellOne方法前面加上Synchronized关键字,使得这个方法,在被任何线程调用时,其他线程就不能再调用,而只能排队等候。这样,结果就完美了。即使两个浏览器是同时运行的,数据也是一个一个减下来的。

例:2.1.1

ServletHello1.java:

package com;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class ServletHello1 extends HttpServlet {

int bookNum=20;

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

PrintWriter pw = response.getWriter();

while (bookNum>0){

onlySellOne(pw);

}

}

void onlySellOne(PrintWriter pw) throws IOException {

if (bookNum > 0) {

pw.println(Thread.currentThread().getName()

" before" bookNum);

pw.flush();

bookNum--;

try {

Thread.sleep(2000);

} catch (Exception e) {

}

pw.println(Thread.currentThread().getName()

" after " bookNum);

pw.flush();

}

}

}

更多请看:https://blog.csdn.net/qq_44594371/article/details/103157775

jsp

0 人点赞