并发编程六:线程安全与共享资源

线程安全与共享资源

介绍

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

弄清楚Java线程执行时共享了哪些资源非常的重要

共享资源

局部变量

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

public int fun(){
    int a=10;
    return a;
}
这个方法就是线程安全的

局部的对象引用

对象的局部引用和基础类型的局部变量不太一样.尽管引用本身没有被共享.但引用所指的对象并没有存储在线程的栈内.

所有的对象都存在共享堆中.

如果在某个方法中创建的对象不会逃逸出(即该对象不会被其它方法获得,也不会被非局部变量引用到)该方法,那么它就是线程安全的.

public void fun(){
    Object obj=new Object();
    //obj do ...
}

//这个方法即使是局部对象引用也是线程安全的,因为每一个线程都会创建一个新的Object对象。

对象成员(即成员变量)

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

以下这段方法代码就不是线程安全的,需要我们作同步处理。

private int count = 0;

public int incr()
{
    return (++count);
}

线程控制逃逸规则

如果一个资源的创建、使用、销毁都在同一个线程内完成,且永远不会脱离该线程的控制,则该资源的使用就是线程安全的.


资源可以是对象、数组、文件、数据库连接、套接字等等.Java中你无需主动销毁对象,所以“销毁”指不再有引用指向对象。

即使对象本身线程安全,但如果该对象中包含其他资源(文件,数据库连接)整个应用也许就不再是线程安全的了


比如2个线程都创建了各自的数据库连接,每个连接自身是线程安全的,但它们所连接到的同一个数据库也许不是线程安全的

2个线程执行如下代码
检查记录X是否存在,不存在则插入X

如果两个线程并发执行可能的情景:
A线程检查记录X是否存在。结果不存在
B线程检查记录X是否存在。结果不存在
A线程插入记录
B线程插入记录

这样就会出现重复插入问题了。

同样的问题也会发生在文件或其他共享资源上.因此,区分某个线程控制的对象是资源本身,还是仅仅到某个资源的引用很重要。

总结

线程安全问题首先要分析共享资源是什么,有时除了程序上的共享资源,还得考虑文件、数据库等资源。

参考

1、http://tutorials.jenkov.com/java-concurrency/thread-safety.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值