线程安全分析

线程安全分析,第1张

线程安全分析

在通过例子分析线程安全之前先 看了解这些 知识
在去看例子会清晰一点

Java有三大变量
		静态变量:在方法区。
		实例变量:在堆当中
		局部变量:在栈中。
 以上三大变量中:

		局部变量永远都不会存在线程安全问题。
		因为局部变量不共享。(一个线程一个栈。)
		局部变量在栈中。所以局部变量永远都不会共享。
	
		实例变量在堆中,堆只有1个。
		静态变量在方法区中,方法区只有1个.
	
		堆和方法区都是多线程共享的,所以可能存在线程安全问题。
	
		局部变量+常量:不会有线程安全问题。
		成员变量:可能会有线程安全问题。
		【成员变量包括实例变量(存储在堆内存)和静态变量(存储在方法区内存)】
		局部变量存储在栈内存当中,栈不共享,不会有线程安全的问题

常见线程安全类

	String
	Integer
	Random
	Vector
	Hashtable
	java.util.concurrent 包下的类
		ArrayList是非线程安全的。vector是线程安全的。
		HashMap Hashset是非线程安全的。Hashtable是线程安全的。
	
	如果使用局部变量的话:
		建议使用: stringBuilder.
		因为局部变量不存在线程安全问题。
		选择stringBuilder.stringBuffer效率比较低。

总结: 实现线程安全有三种方式:1.无共享变量2.共享变量不可变3.同步

下面请跟我分析一下代码是否存在线程安全的问题,全部看完相信会有很大帮助
例一:

	public class MyServlet extends HttpServlet {
		 // 是否安全?
		 Map map = new HashMap<>();   //不安全 因为HashMap当中没有synchronized修饰 是非安全的
		 // 是否安全?
		 String S1 = "...";    //安全 因为String的不可变类 属于共享变量不可变
		 // 是否安全?
		 final String S2 = "...";   //安全的 本身String就是线程安全的 加上final就更是了
		 // 是否安全?
		 Date D1 = new Date();  //不安全 日期类不属于线程安全的
		 // 是否安全?
		 final Date D2 = new Date();  //不安全 虽然final Date D2 的 final修饰的 
		 //但是他new Date(); 里面 的年月日会变  总结 日期是可变类 而字符串是不可变的
	}

例二

public class MyServlet extends HttpServlet {
		 // 是否安全?
		 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++;
		 }
		}
		
		

例三

spring IOC
		@Aspect
		@Component
		public class MyAspect {
		 // 是否安全?
		 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)); //计算耗时  通过切面的功能,把耗时功能给抽离出来
		 }
		}
		
		

例四

//MVC的三层调用 
		public class MyServlet extends HttpServlet {
		 // 是否安全
		 private UserService userService = new UserServiceImpl();
		 
		 public void doGet(HttpServletRequest request, HttpServletResponse response) {
		 userService.update(...);
		 }
		}
		public class UserServiceImpl implements UserService {
		 // 是否安全
		 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) {
		 // ...
		 }
		 }
		}
		
		

例五

	public class MyServlet extends HttpServlet {
		 // 是否安全
		 private UserService userService = new UserServiceImpl();
		 
		 public void doGet(HttpServletRequest request, HttpServletResponse response) {
		 userService.update(...);
		 }
		}
		public class UserServiceImpl implements UserService {
		 // 是否安全
		 private UserDao userDao = new UserDaoImpl();
		 
		 public void update() {
		 userDao.update();
		 }
		}
		
		public class UserDaoImpl implements UserDao {
		 // 是否安全
		 private Connection conn = null;
		 public void update() throws SQLException {
		 String sql = "update user set password = ? where username = ?";
		 conn = DriverManager.getConnection("","","");
		 // ...
		 conn.close();
		 }
		}
		
		

例七

		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();
		 }
		}
		//其中 foo 的行为是不确定的,可能导致不安全的发生,被称之为外星方法
		public void foo(SimpleDateFormat sdf) {
		 String dateStr = "1999-10-11 00:00:00";
		 for (int i = 0; i < 20; i++) {
		 new Thread(() -> {
		 try {
		 sdf.parse(dateStr);
		 } catch (ParseException e) {
		 e.printStackTrace();
		 }
		 }).start();
		 }
		}
		
		

看完相信你一定有所收获,一起加油!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5717924.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存