考虑个问题,为什么要独占?
假如你的对象状态永远是不会改变的,那么就不用考虑这个问题了。
达到独占的基本策略:
一.确保对象永远不会出现不一致状态的情况
例如保证对象的无状态性:
class stateless{
public int add(int a,int b){
retun a+b;
}
}
或者可以把属性引用申明为为final
class TT{
private final int a;
TT(int a){
this.a =a ;
}
public int addA(int b){return a+b;}
}
用不变的对象来判断状态
flyweight模式
在构造函数之前不能访问对象数据
二.加锁保证一个对象同时只能被一个线程访问
锁其实是个对象,锁监视器监视该对象是否有线程进入
如何进行集合遍历(对集合操作的可能无限多,不可能每个方法都加锁):
1)聚合锁
class testarray {
private int a[];
public synchronized void printAll() {
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
}
2)索引化遍历和客户端锁
synchronized(v){
for(int i=0;i<v.size();i++)
{
v.get(i);
}
}
这样做持有锁时间太长,有活跃性问题
改进:
object[] objs = null;
synchronized(v){
objs = new Object[v.size()];
for(int i=0;i<v.size();i++)
{
objs[i] = v.get(i);
}
}
for(int i=0;i<objs.length;i++)
{
objs[i].operator();
}
不过这种方式以破坏封装为原则,假如这个类被改变了,那么很有可能出问题。
3)失败即放弃
就是每次对集合添加,删除对象,都将更改版本号。遍历的时候比较版本号,假如对不上就失败。
synchronized(List.this){
if(currVer !=version)
throw Exception();
}
单例的问题:
方案一:非延迟加载单例类
Java代码
public class Singleton {
private Singleton(){}
private static final Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
public class Singleton {
private Singleton(){}
private static final Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
方案二:简单的同步延迟加载
Java代码
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}
方案三:双重检查成例延迟加载
目的是避开过多的同步,
但在Java中行不通,因为同步块外面的if (instance == null)可能看到已存在,但不完整的实例。
JDK5.0以后版本若instance为volatile则可行
Java代码
public class Singleton {
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Singleton {
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
方案四:类加载器延迟加载
Java代码
public class Singleton {
private static class Holder {
static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return Holder.instance;
}
}
死锁:
线程1持有A锁正等待进入B锁。线程2持有B锁正等待进入A锁。
如果线程1和2都以同样的顺序,例如先A后B,或者先B后A那么就不会死锁。
例:
解决方法:
java存储模型:(请认真阅读JAVA语言规范第17章)
1.假设每个线程都运行在不同的CPU上
2.模型容许一个线程不知道被另外一个线程处理的值的情况。
3.模型不会明确指定上述策略是由编译器,CPU,缓存控制器还是其他机制来执行。
主要围绕的问题:
原子性 非long和double的原子类型,long和double加volatile也可保证原子性。
可见性 同步和volatile都能保证可见性
顺序化 保证同步方法和块的相关顺序
三.隐藏或者限制对象的使用权限,结构性的保证只能被一个线程使用该对象。
通过封装技术来实现
1.跨方法限制
1).在方法未必泄露引用。
2).对象只存在于一次会话中
3).调用者或者接受者拷贝对象,而非直接操作引用
2.线程内限制
1)一个线程一个会话
2)一个线程维护一个私有变量
3).ThreadLocal
3.对象内限制
适配器
子类化
4.组限制,对一组资源访问的问题,例如令牌环
四:构造和重构类
重构需要处理的问题:
1.锁占用太长时间
2.锁太多
3.一个锁保护多个方面
4.锁只能支持很多的并发数
5.锁没起到预想效果
解决方案:
1.减少同步(看情况进行处理,如果不能接受陈旧数据,需要对存储方法进行同步)
2.双重检测,减少同步。如果检测的是对象,例如if (instance==null),需要有volatile关键字,否则有可见性问题。
3.分解同步(分解类,分解锁)
4.只读适配器,弱化功能,对原生类进行包装,例如Collections.UnmodifiableCollection
5.写拷贝
内部写拷贝,一般用于本次改变,下一次通知才生效。
6.乐观更新(把同步的粒度缩减到最小)
1)得到当前线程状态的一个拷贝(持有锁的时候)
2)创建一个新的对象(不持有锁)
3)只有在老状态被获取后并且没有改变才能被更新。
比较并交换
虽然JAVA不能访问底层CAS代码,但是原则上编译器会优化该代码。
7.开放容器
假如访问一个对象的A,B部分,分别需要获取不同的锁。那么有可能死锁。可以在容器上加一个大锁,只有获取了该锁才可以获取A锁,或者B锁。
五。锁工具
解决同步不能回退
改变锁的语义
可以做同步的访问控制
方法块内严格限制
例如:Mutex类
锁管理器实现锁的顺序化
读写锁,当读的比例远远大于写
- 大小: 35.5 KB
- 大小: 55.5 KB
- 大小: 97.4 KB
- 大小: 49.8 KB
- 大小: 25.2 KB
- 大小: 68.7 KB
- 大小: 30.3 KB
- 大小: 42.7 KB
- 大小: 67.9 KB
分享到:
相关推荐
本篇文章将深入探讨Activiti中的一个重要概念——排他网关(Exclusive Gateway),也称为独占网关。排他网关是流程设计中的一个关键组件,它在流程执行时起到决策的作用,根据预定义的条件来决定流程应该如何继续。 ...
- **块级元素**:独占一行,如 `<p>`, `<ul>`, `<ol>`, `<li>`, `<header>`, `<footer>`, `<nav>`, `<div>` 等。 - **行内元素**:与其他行内元素共存一行,如 `<span>`, `<i>`, `<em>`, `<b>`, `<strong>`, `<u>`, ...
- **排他锁**:独占资源,禁止其他事务读取或修改。 ##### 4. 锁和性能 - **选择合适的锁类型**:平衡并发性和性能。 - **死锁处理**:自动检测并解决死锁问题。 #### 八、XQuery简介 XQuery是一种用于查询XML文档...
虚拟设备技术和SPOOL系统使得独占设备变为共享,提高设备利用率。 三、嵌入式系统 嵌入式系统是针对特定应用设计的计算机系统,具有高度定制性,强调可靠性、成本、体积和功耗。它们使用专用的嵌入式CPU,软件注重...
- 第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及BCNF(博科斯范式),理解并应用规范化理论。 8. **数据库恢复技术**: - REDO和UNDO日志,用于事务故障恢复。 - CHECKPOINT机制,提高恢复效率。 9. ...
笔记的第二部分介绍了计算机网络基础知识,特别是操作系统。操作系统是计算机系统的核心,负责管理硬件和软件资源,提供用户界面。操作系统可分类为单用户、批处理、分时、实时、网络、分布式和嵌入式等类型。其主要...
这种心理可能导致幼儿独占玩具,不愿意与他人分享,容易引发冲突。 3. **教育策略**:面对幼儿不愿分享的情况,教师可以通过观察和对话理解孩子的感受,如案例中的陈阳小朋友。通过询问和引导,让孩子意识到自己的...
虚拟设备技术是通过共享设备来模拟独占型设备的动作,使独占型设备成为共享设备,从而提高设备利用率和系统的效率。SPOOL 系统是实现虚拟设备技术的硬件和软件系统,又称 Spooling 系统或假脱机系统。 作业调度算法...
HTML 笔记 clear:清除浮动 clear:left;清除前面左浮动的元素。 使前面左浮动的元素恢复独占一行的特性。 clear:right;清除右浮动。 clear:both;清除两边的浮动。(左,右)clear:none;不清除浮动。 说明:清除浮动...
"哔哩哔哩JUC狂老师笔记.zip"中的笔记内容,显然聚焦于讲解如何有效地利用JUC库来提升并发性能和程序的正确性。下面,我们将深入探讨JUC中的关键知识点。 1. **锁机制**: - **synchronized**:Java内置的关键字,...
### FreeRTOS开发笔记知识点概述 #### 一、FreeRTOS简介与特点 - **FreeRTOS**:免费实时操作系统(Free Real-Time Operating System),是一款为微控制器量身打造的轻量级实时操作系统。 - **精简内核**:...
根据提供的“软考网络工程师复习笔记”的部分内容,我们可以总结并扩展一些重要的IT知识点,以便更好地理解和准备相关的考试。 ### 第一章 计算机基础知识 #### 一、硬件知识 - **计算机系统的组成**:包括硬件...
2015年Q3,全球PC出货量排名第一的联想销量接近1500万台,同比下滑4%,排名第二的惠普销量1370万台,同样下滑了4%。 用户使用笔记本电脑的时间缩短且集中 笔记本生命周期延长 笔记本电脑市场调研报告全文共24页,...
**CCNA知识点详解** ...以上是CCNA笔记中的主要知识点,涵盖了网络架构、OSI模型、物理层特性、数据链路层、网络层以及传输层的核心概念,还有CISCO设备管理和初始化。理解和掌握这些知识点对于CCNA的学习至关重要。
### 操作系统复习笔记知识点详解 #### 一、操作系统在计算机系统中的地位 操作系统作为计算机系统的核心软件,其重要性不言而喻。它在计算机系统中扮演着多个关键角色,包括但不限于: - **控制CPU的工作**:操作...
软考网络工程师学习笔记(完整版) 计算机基础知识 计算机系统的组成包括硬件系统和软件系统。硬件系统分为三种典型结构:单总线结构、双总线结构和采用通道的大型系统结构。中央处理器 CPU 包含运算器和控制器。 ...
### vc++6.0使用笔记 #### 模态对话框与非模态对话框 - **模态对话框**:这种类型的对话框会独占用户的输入。一旦打开模态对话框,用户无法与应用程序的其他部分进行交互,直到关闭该对话框为止。这通常用于需要...
本学习笔记旨在通过问题与解答的形式,帮助读者深入理解和应用该条例。 1. **什么是计算机软件?** 计算机软件,又称程序或应用,包括计算机程序及其有关文档。程序是指为了得到某种结果而可以由计算机等具有信息...
中级软考笔记网络工程师 在计算机系统中,硬件系统是指计算机的物理组件,包括中央处理器(CPU)、存储系统、输入/输出(I/O)设备和总线等。 计算机系统的组成包括硬件系统和软件系统。 硬件系统分为三种典型...