17.Servlet线程安全问题
1.Servlet是单实例多线程环境下运行的。
2.存在线程安全问题的情况:
-多线程并发
-有共享的数据
-共享数据有修改操作
3.JVM中,可能存在线程安全问题的数据
-局部变量内存空间不共享,一个线程一个栈,局部变量在栈中存储,局部变量不会存在线程安全问题。
-常量不会被修改,所以常量不会存在线程安全问题。
-所有线程共享一个堆
*堆内存中new出来的对象在其中存储,对象内部有"实例变量",所以实例变量的内存多线程是共享的。
实例变量多线程同时访问,并涉及到修改操作的时候就会存在线程安全问题。
-多有线程共享一个方法区
*方法区中有静态变量,静态变量的内存也是共享的,若涉及到修改操作,静态变量也存在线程安全的问题。
4.线程安全问题发生在数据库中。
例如:多个线程共享同一张表,并且同时去修改表中的一些记录。那么这些记录存在线程安全问题。
解决方案:
-第一种解决方案:在java程序中使用synchronized关键字,线程排队执行,自然不会再数据库中并发,解决线程安全问题。
-第二种方式:行级锁【悲观锁】
-第三种方案:事物隔离级别高,例如,串行化
-第四种方案:乐观锁....
5.javase如何解决线程安全问题
5.1 不使用实例变量,尽量使用局部变量
5.2 若必须使用实例变量,可以考虑将该对象变成多例对象,一个java线程一个java对象,实例变量的内存也不会共享。
5.3 若必须使用单例,那就只能使用synchronized线程同步机制,线程一旦排队执行,则吞吐量降低,降低用户体验。
(使用static修饰的成员变量是类变量,属于该类本身.
没有使用static修饰的成员变量是实例变量,属于该类的实例。)
6.解决Servlet线程安全问题
6.1 不使用实例变量,尽量使用局部变量。
6.2 Servlet必须是单例的,所以考虑使用synchronized,线程同步机制。