软件构造第十章复习(二)

保证线程安全的方法:

限制可变变量的共享:

局部变量保存在线程栈中,每个调用都有自己的变量副本, 局部变量如果是对象的引用,则要确保不能引用任何其他线程可访问的对象(针对可变对象)。
避免全局变量的使用:全局静态变量不会自动受到线程访问限制, 如果使用了全局静态变量,则应说明只允许一个线程使用它们,所以在多线程中应取消全局变量。

用不可变的共享变量:

不可变解决了因为共享可变数据造成的竞争,并简单地通过使用共享数据不可变来解决它。
一种常见的方式是使用final: final变量不允许再赋值,所以声明为final的变量可以安全地从多个线程访问。因为这种安全性只适用于变量本身,仍然必须确保变量指向的对象是不可变的。

将共享数据封装在线程安全的数据类型中:

将共享的可变数据存储在线程安全的数据类型中。因为线程安全的数据类型性能较差,所以Java对一些可变数据类型提供两种形式供选择:线程安全的和线程不安全的。
例:StringBuffer 和 StringBuilder都是可变数据类型,功能基本相同
StringBuffer是线程安全的,StringBuilder不是
StringBuilder性能更好,推荐在单线程程序中使用

Java提供的线程安全的Collections类型版本确保了方法是原子的,也就是动作的内部操作不会同其他操作交叉,不会产生部分完成的情况。

使用同步机制来防止线程同时使用变量:

防止多个线程同时访问共享数据,所以并发模块彼此间采用同步的方式共享内存,以解决竞争带来的问题。

常用的方法是使用锁机制:锁是一种抽象,某时刻最多只允许一个线程拥有锁。
锁的获取:如果锁被其他线程拥有,将进入阻塞状态,等待锁释放后,再同其他线程竞争获取锁的拥有权。
锁机制可以确保锁的拥有者始终查看最新的数据,避免了reordering问题。

同步语句的锁: 同步区域提供了互斥功能: 一次只能有一个线程处于由给定对象的锁保护的同步区域中。如:
在这里插入图片描述
锁只能确保与其他请求获取相同对象锁的线程互斥访问,如果其他线程没有使用synchronized(obj)或者利用了不同的锁,则同步会失效,需要仔细检查和设计同步块和同步方法。

同步方法的锁:
当线程调用同步方法时,它会自动获取该方法所在对象的内部锁,并在方法返回时释放它。即使返回是由未捕获的异常引起的,也会释放锁。
当一个线程在执行一个对象的同步方法时,所有其他线程如果调用同一对象的同步方法块,则会挂起执行,直到第一个线程针对此对象的操作完成。
实现的两种方法如下:
在这里插入图片描述
在这里插入图片描述

注:同步方法不用指定锁,但同步语句/块必须指定锁。
在涉及到线程安全之后,要在ADT的spec中说明是不是线程安全的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值