JAVA中的多线程并发环境下数据的安全问题(概述)
JAVA中的多线程并发环境下数据的安全问题(概述)
-
什么时候数据在多线程并发的环境下会存在安全隐患? 三个条件: 条件1:多线程并发 条件2:有共享数据 条件3:共享数据有修改的行为 满足以上三个条件,就会存在线程安全问题 怎么解决线程安全问题: 当多线程并发的环境下,有共享数据,并且这个数据还会被修改,此时就存在线程 安全问题,该如何解决: 线程排队执行(不能并发) 用排队执行解决线程安全问题 这种机制被称为:线程同步机制 实际上就是线程不能并发了,线程必须排队执行,会牺牲一部分效率。 只有数据安全了,效率才有意义 线程同步: 1、异步编程模型: 线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1, 也就是“多线程并发”(效率较高) 2、同步编程模型: 线程t1和线程t2,在线程t1执行的时候,必须等待t2线程执行结束,或者线程t2 执行的时候,必须等待t1线程执行结束,两个线程之间发生了等待关系。 效率较低。 Java中有三大变量: 1、实例变量:在堆中 2、静态变量:在方法区中 3、局部变量:在栈中 以上三大变量中: 局部变量和常量永远不会存在线程安全问题,因为局部变量不共享(一个线程一个栈) 实例变量在堆中,堆只有一个, 静态变量在方法区中,方法区只有一个 堆和方法区都是多线程共享的,所以可能存在线程安全问题 StringBuilder和StringBuffer 如果使用局部变量的话: 建议使用StringBuilder 因为局部变量不存在线程安全问题,使用StringBuilder效率更高 ArrayList是非线程安全的 Vector是线程安全的 HashSet和HashMap是非线程安全的 Hashtable是线程安全的 总结: synchronized三种写法: 第一种:同步代码块(灵活) synchronized(线程共享对象){ 同步代码块 } 第二种:在实例方法上使用synchronized 表示共享对象一定是this 并且同步代码块是整个方法体 第三种:在静态方法上使用synchronized 表示找类锁 类锁永远只有一把 就算创建了100个对象,也只有一把类锁 对象锁:1个对象1把锁 类锁:对象再多,也只有一把锁 以后的开发中如何解决线程安全问题: 是一上来就synchronized线程同步吗? 不是,synchronized会让程序的执行效率降低,用户体验不好,系统的用户吞吐量 降低,用户体验差,在不得已的情况下再选择线程同步机制 第一种方案:尽量使用“局部变量”代替“实例变量”和“局部变量”。 第二种方案:如果必须是实例变量,那么可以考虑创建多个对象,这样实例变量的内存 就不共享了,(1个线程对应1个对象,100个线程对应100个对象,对象不共享, 就没有数据安全问题了) 第三种方案:如果不能使用局部变量,对象也不能创建多个,这个时候就只能选择 synchronized线程同步机制了。
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
非法的Unicode 转义问题