- 首页 > 生活 > >
但注意它们多个方法的组合不是原子的!我们采用代码进行简单解释:
/*下述的单个方法都是原子且安全性的*/ Hashtable table = new Hashtable();new Thread(()->{table.put("key", "value1");}).start();new Thread(()->{table.put("key", "value2");}).start();/*但当这些方法组合起来,就无法保证其线程安全性*/ Hashtable table = new Hashtable();// 线程1,线程2都执行时,可能出现下述情况// 线程1get==null,线程2get==null,线程2put,线程1put;导致线程安全性错误出现if( table.get("key") == null) { table.put("key", value);}
常见题型分析我们直接给出代码来进行题型分析:
/*题目1*/// MyServlet是Servlet类,应用于Tomcat的多线程上public class MyServlet extends HttpServlet {// 是否安全?不是,不属于线程安全类Map<String,Object> map = new HashMap<>();// 是否安全?是,属于不变类型String S1 = "...";// 是否安全?是,属于不变类型final String S2 = "...";// 是否安全?不是,不属于线程安全类Date D1 = new Date();// 是否安全?是,属于不变类型final Date D2 = new Date();public void doGet(HttpServletRequest request, HttpServletResponse response) {// 使用上述变量}}/*题目2*/public class MyServlet extends HttpServlet {// 是否安全?不是,底层使用Impl,里面包含了count这个共享数据,且没有使用锁private UserService userService = new UserServiceImpl();public void doGet(HttpServletRequest request, HttpServletResponse response) {userService.update(...);}}public class UserServiceImpl implements UserService {// 记录调用次数private int count = 0;public void update() {// ...count++;}}/*题目3*/// 这里是Spring的@Aspect,属于单例,也是共享@Aspect@Componentpublic class MyAspect {// 是否安全? 不是,start属于共享数据private long start = 0L;@Before("execution(* *(..))")public void before() {start = System.nanoTime();}@After("execution(* *(..))")public void after() {long end = System.nanoTime();System.out.println("cost time:" + (end-start));}}/*题目4*/public class MyServlet extends HttpServlet {// 是否安全 是,调用Dao,不具有可变参数private UserService userService = new UserServiceImpl();public void doGet(HttpServletRequest request, HttpServletResponse response) {userService.update(...);}}public class UserServiceImpl implements UserService {// 是否安全 是,调用Dao,不具有可变参数private UserDao userDao = new UserDaoImpl();public void update() {userDao.update();}}public class UserDaoImpl implements UserDao {public void update() {String sql = "update user set password = ? where username = ?";// 是否安全 是,因为不具有可变参数try (Connection conn = DriverManager.getConnection("","","")){// ...} catch (Exception e) {// ...}}}/*题目5*/public class MyServlet extends HttpServlet {// 是否安全 不是,具有conn可变参数private UserService userService = new UserServiceImpl();public void doGet(HttpServletRequest request, HttpServletResponse response) {userService.update(...);}}public class UserServiceImpl implements UserService {// 是否安全 不是,具有conn可变参数private UserDao userDao = new UserDaoImpl();public void update() {userDao.update();}}public class UserDaoImpl implements UserDao {// 是否安全 不是,具有conn可变参数private Connection conn = null;public void update() throws SQLException {String sql = "update user set password = ? where username = ?";conn = DriverManager.getConnection("","","");// ...conn.close();}}/*题目6*/public class MyServlet extends HttpServlet {// 是否安全 但是这里是安全的// 虽然底层将conn创建在堆里,但是impl层创建了多个userDao对象,导致产生了多个conn不产生安全问题private UserService userService = new UserServiceImpl();public void doGet(HttpServletRequest request, HttpServletResponse response) {userService.update(...);}}public class UserServiceImpl implements UserService {public void update() {UserDao userDao = new UserDaoImpl();userDao.update();}}public class UserDaoImpl implements UserDao {// 是否安全 不是,具有conn可变参数private Connection = null;public void update() throws SQLException {String sql = "update user set password = ? where username = ?";conn = DriverManager.getConnection("","","");// ...conn.close();}}/*题目7*/public abstract class Test {public void bar() {// 是否安全 不是,局部变量交付给抽象类,抽象类后续子类可能会产生修改:称为外星方法SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");foo(sdf);}public abstract foo(SimpleDateFormat sdf);public static void main(String[] args) {new Test().bar();}}
经验总结扩展阅读
-
eliauk和aurora是情侣名吗,eliauk和aurora是情侣名吗?
-
-
-
-
-
-
电饭煲没放内胆就倒水的后果,向未放内胆的电饭煲里倒了水后怎么办?
-
-
男子山中捡到玉佩,拿给瞎婆婆辨认,瞎婆婆说来历不凡需慎用
-
-
-
-
-
-
健康周谈|房事后,为何女生会产生腹痛感?医生:5个原因有必要了解一下!
-
-
-
|二十年前母亲卖房给姑姑治病,二十年后我结婚,姑姑送房又送车
-
高速救援12122为啥打不通,高速公路上的紧急服务电话是多少
-
白娘子 网红胖猴仔扮白娘子,选个教练当“相公”,网友:这是条大蟒吧