返回
安全工程师

java的线程安全是什么

作者:lansebaiwen2025-01-03 10:5855

这个还真不能一句话概况,我博客写了一长篇关于线程安全的,我提炼了下面这段,看懂也基本够了:

单线程不会有安全问题,多线程编程才会有安全问题,根本在于是否存在critical resource竞争资源,如果多线程不会访问竞争资源就不存在安全问题,否则则要处理,

什么是竞争资源呢,具体如下:

如果是各自访问其上下文context的资源,比如kafka consumer partition worker线程访问各自的storage则是互相不打扰的;

如果执行的某个方法内只用到了局部变量,由于局部变量位于各自thread的栈里,所以互不干扰;

如果执行的某个方法用到了传入的变量,也就是所谓的形式参数变量,则要看这个传入的变量是否是object,如果只是普通的参数则没关系,如果是对象,要看对象是否是同一个引用,不同引用没有关系;

如果执行的某个方法内用到了同一个引用,不管是传入的还是外部全局的变量,比如log4的logger,由于log4已经做好了线程安全写log,所以不用担心;

如果执行的某个方法内用到了同一个引用:

i)但是只是读没有写,读和读是没有冲突的,也没有关系;

ii)都有写,但是写不依赖于读,即线程不需要获取“最新”数据就可以直接写入覆盖,这种情况也没有关系;

iii)都有写,而且写依赖于读到最新数据,则需要处理;

线程安全的对象:针对数据,或者说是对象的属性;

线程安全的场景:多线程修改及读取对象的属性;

线程安全的需求:不同线程可以正确的修改及读取对象的属性,不会出现读取了更新前的属性值等情况;

线程安全如何保障:方法一,加同步锁,同一个对象同一个时间点只允许同一个操作;方法二,针对多线和场景优化,从外部看,针对一个对象允许并发操作,但是采用变通的方法去保障对象可以被正确的更新与读取。比如ConcurentHashMap采用了拆分子区块,每个区块单线程同步操作,但是由于存在多个区块,因此从这个对象的外部看,是多线程场景下,允许并发访问,且是线程安全的。

学生类:

class A{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }} //学生类使用方法: public class test(){ public static void main(String[] args) { A[] students = new A; //创建2个学生的学生数组 A as= new A(); as.setAge(15); as.setName(“tom”); A as1= new A(); as1.setAge(16); as1.setName(“cat”); A[] a={as,as1}; //动态创建学生数组 for (A st : a) {//遍历数组 System.out.println(st.getName()+”;”); }}}

想了解更多Java相关,百度搜索圈T社区www.aiquanti.com,免费视频教程。纯干货

0点赞
0反对
0举报
0收藏
0分享
海报
分享到: