个人不喜欢学习时候把所有东西都事无巨细的记录下来,我认为只记录重要的就行,其他的通过短时间练习可以很快记住的。这里记录一下Servlet的线程安全问题;
首先要明白,Servlet引擎只在客户端第一次发送请求时候创建Servlet对象,这就意味着客户端多次请求都是由同一个Servlet实例处理的。所以这时候有两种情况:
1.如果请求访问的是局部变量,那么这个局部变量是属于该线程的,不存在安全问题,因为每一个局部变量都是独立的
2.如果请求访问的是全局变量,即这个变量是属于这个sevlet对象的,所有线程都可以更改,不是独立的,这时候就存在线程安全问题。并发访问时,可能A请求先更改了temp变量的值,之后B请求又更改了temp变量的值,然后A请求获取变量的值,B请求获取变量的值,这是不应该的,因为A,B请求获取到的值都是更改了两次的。解决办法:
(1):使用synchronized 将更改变量的代码加上锁,这样B请求就必须等A请求被处理完之后才能被处理,这样就能获取到正确的值了,但是有一个问题,这样子就相当于是将所有请求构成一个队列了,先进先出,请求必须一个一个的被处理,这样子时间耗费太大了.
(2):实现SingleThreadModel接口,这样会以单线程的模式来进行处理,为每个线程都创建一个Servlet实例,但是这样感觉并没有解决本质问题,而且创建实例也是有数量上限的,最多是20个,多了的话就先挂起了,另外说一下,servlet在创建的时候,会先判断已经创建的sevlet是不是一个单线程(SignleThreadModel),是的话就新创建一个实例,不是的话就加载原来的实例,这也是为什么继承了SingleThreadModel接口就能创建多个实例的原因。
但是这没有真正的解决线程安全问题,而且这个方法也已经被废除了。
综上,可以看到servlet不是线程安全的,所以尽量避免设计全局变量,真的有的话,使用上面两种方法,同步,,不太理解。