欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 006 线程安全

006 线程安全

2025/9/26 8:05:23 来源:https://blog.csdn.net/m0_46695127/article/details/140207797  浏览:    关键词:006 线程安全

文章目录

  • 临界资源
  • 线程安全
    • 基本概念
      • *何谓竞态条件*
      • *何谓线程安全*
    • 对象的安全
      • 局部基本类型变量
      • 局部的对象引用
      • 对象成员(成员变量)
    • 不可变性

临界资源

临界资源是一次仅允许一个进程使用的共享资源。各进程采取互斥的方式,实现共享的资源称作临界资源。属于临界资源的硬件有,打印机,磁带机等;软件有消息队列,变量,数组,缓冲区等。诸进程间采取互斥方式,实现对这种资源的共享。

线程安全

基本概念

何谓竞态条件

当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。
导致竞态条件发生的代码区称作临界区。
在临界区中使用适当的同步就可以避免竞态条件,如使用synchronized或者加锁机制。

何谓线程安全

允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。

对象的安全

局部基本类型变量

局部变量存储在线程自己的栈中。也就是说,局部变量永远也不会被多个线程共享。所以,基础类型的
局部变量是线程安全的。下面是基础类型的局部变量的一个例子:


public class ThreadTest {public static void main(String[]args){MyThread share = new MyThread();for (int i=0;i<50;i++){new Thread(share,"线程"+i).start();}}
}
class MyThread implements Runnable{public void run() {int a =0;++a;System.out.println(Thread.currentThread().getName()+":"+a);}
}

无论多少个线程对run()方法中的基本类型a执行++a操作,只是更新当前线程栈的值,不会影响其他线程,也就是不共享数据;

局部的对象引用

对象的局部引用和基础类型的局部变量不太一样,尽管引用本身没有被共享,但引用所指的对象并没有存储在线程的栈内。所有的对象都存在共享堆中。
如果在某个方法中创建的对象不会逃逸出(即该对象不会被其它方法获得,也不会被非局部变量引用到)该方法,那么它就是线程安全的。
实际上,哪怕将这个对象作为参数传给其它方法,只要别的线程获取不到这个对象,那它仍是线程安全的。


public void method1(){LocalObject localObject = new LocalObject();localObject.callMethod();method2(localObject);
}
public void method2(LocalObject localObject){localObject.setValue("value");
}

对象成员(成员变量)

对象成员存储在堆上。如果两个线程同时更新同一个对象的同一个成员,那这个代码就不是线程安全的。


public class ThreadTest {public static void main(String[]args){NotThreadSafe sharedInstance = new NotThreadSafe();new Thread(new MyRunnable(sharedInstance)).start();new Thread(new MyRunnable(sharedInstance)).start();}
}
class MyRunnable implements Runnable{NotThreadSafe instance = null;public MyRunnable(NotThreadSafe instance){this.instance = instance;}public void run(){this.instance.add(" "+Thread.currentThread().getName());System.out.println(this.instance.builder.toString());}
}
class NotThreadSafe{StringBuilder builder = new StringBuilder();public void add(String text){this.builder.append(text);}
}

不可变性

通过创建不可变的共享对象来保证对象在线程间共享时不会被修改,从而实现线程安全。如下示例:


public class ImmutableValue{private int value = 0;public ImmutableValue(int value){this.value = value;}public int getValue(){return this.value;}
}

请注意ImmutableValue类的成员变量 value 是通过构造函数赋值的,并且在类中没有set方法。这意味着一旦ImmutableValue实例被创建, value 变量就不能再被修改,这就是不可变性。但你可以通过getValue()方法读取这个变量的值。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词