
1. 对象的状态: 对象的状态是指存储在状态变量中的数据. 对象的状态可以包括依赖于对象的其他域. 对象的状态包含任何可能影响其外部可见行为的数据.
2. 一个对象是否是线程安全的取决于它是否被多个线程访问. 这是指在程序中访问对象的方式,而不是对象的功能. 当多个线程访问某个状态变量并且其中一个线程执行写操作时,必须使用同步机制来协调这些线程对变量的访问. 同步机制包括同步的,易变的变量,显式锁和原子变量.
3. 有三种方法可以解决线程安全问题:
1)不要程之间共享此状态变量
2)将状态变量修改为不可变变量
3)访问状态变量时使用同步
4. 线程安全性的定义: 当多个线程访问一个类时,无论运行时环境使用哪种调度方法或如何交替执行这些线程,并且在调用代码中都不需要进行其他同步,此类可以显示正确的行为,然后此类称为线程安全.
5. 无状态变量必须是线程安全的,例如局部变量.
6. 读-修改-写操作顺序. 如果后续操作取决于先前读取的值,则此序列必须串行执行. 在并发编程中,由于执行时间不适当而导致的错误结果是非常重要的情况,称为竞争条件. 竞赛条件最常见的类型是在检查后执行的操作,而下一个操作则由可能出现故障的观察结果确定.
7. 复合操作: 为避免竞争情况,有必要在某个线程修改变量时防止其他线程以某种方式使用此变量,以确保其他线程只能在完成之前或之后修改操作. 状态,而不是在修改状态的过程中. 假设有两个操作A和B. 如果查看执行A的线程,则当另一个线程执行B时,要么B被完全执行,要么B根本不执行,那么A和B彼此是原子的. 原子操作是指对于所有访问相同状态的操作,该操作都是以原子方式执行的操作.

为确保线程安全,读-修改-写序列必须是原子序列,这称为复合操作. 复合操作包含一组必须原子执行以确保线程安全的接口.
8. 将状态添加到无状态类时,如果此状态完全由线程安全的对象管理,则此类仍然是线程安全的. (例如原子变量)
9. 如果多个状态相关并且需要同时修改,则对多个状态的操作必须是串行的并且需要同步. 为了保持状态一致性,所有相关状态变量都需要在单个原子操作中进行更新.
10. 内置锁: 同步(对象){sync block}
Java的内置锁等效于互斥锁,这意味着最多只有一个线程可以持有此锁. 当线程A试图获取线程B持有的锁时,线程A必须等待或阻塞,直到线程B释放该锁为止. 如果B从不释放锁,那么A也将永远等待.
11. 重入: 当一个线程请求另一个线程持有的锁时,请求线程将阻塞. 但是,由于内置锁是可重入的,因此,如果线程尝试获取自身已持有的锁,则请求将成功. 重新进入意味着获取锁的操作的粒度是线程,而不是调用. 实现重入的一种方法是为每个锁关联获取计数值和所有者线程. 当计数值为0时,该锁被认为没有任何线程持有. 当线程请求未持有的锁时,JVM将记录该锁的持有者并将获取计数设置为1. 如果线程再次获取该锁,则计数值将增加,并且当线程退出同步代码块时,计数值将相应减少. 当计数值为0时,将释放锁定.
12. 对于可能由多个线程同时访问的变量状态变量,在访问它时需要保持相同的锁. 在这种情况下,我们说状态变量受此锁保护.
每个共享变量和可变变量应仅受一个锁保护,以便维护人员知道它是哪个锁.
常见的锁定约定是将所有变量状态封装在对象内部,并提供对象的内置锁(此)以同步访问变量状态的所有代码路径. 在这种情况下,对象状态下的所有变量都受对象的内置锁保护.
13. 错误的并发性: 确保同步代码块不要太小,并且不要将原子操作拆分为多个同步代码块. 您应该尝试从同步代码块中分离不影响共享状态并且执行时间较长的操作,以便在执行这些操作期间,其他线程可以访问共享状态.

14. 可见性: 为了确保多个线程之间的内存写操作可见,必须使用同步机制.
15. 锁定和可见性: 当线程B执行受锁保护的同步代码块时,您可以程A之前的同一同步代码块中看到所有操作的结果. 如果没有同步,则无法实现上述保证. 锁定的含义不仅限于互斥行为,还包括内存可见性. 为了确保所有线程都能看到共享变量的最新值,所有执行读或写操作的线程必须在同一锁上同步.
16. volatile变量: 将变量声明为volatile时,编译器和运行时将注意到此变量是共享的,因此对该变量的操作不会与其他内存操作重新排序. 易失性变量将不会缓存在处理器看不到的寄存器或其他地方线程安全问题代码,因此在读取易失性变量时,始终会返回最近写入的值. volatile的语义不足以确保增量操作的原子性,除非您可以确保只有一个线程对该变量执行写操作. 原子变量提供“读取-修改-写入”原子操作,通常用作更好的易失性变量.
17. 锁定机制可以确保可见性和原子性,而可变变量只能确保可见性.
18. 仅当满足以下所有条件时,才应使用易失性变量:
1)写入变量并不取决于变量的当前值(没有读取-判断-写入序列),也可以确保仅单个线程更新变量的值.
2)变量不会与其他状态变量一起包含在不可变条件中
3)访问变量时无需锁定
19. 堆栈关闭: 在堆栈关闭中,只能通过局部变量访问对象. 维护线程关闭的一种更为标准化的方法是使用ThreadLocal. 此类可以将线程的值与保存该值的对象相关联. ThreadLocal使用访问接口或方法,例如get和set. 这些方法分别用于. 此变量的每个线程都有一个独立的副本,因此get总是在调用set时返回当前正在执行的线程设置的最新值.
20. 在并发程序中使用和共享对象时,可以使用一些策略,包括:

1)线程关闭: 一个线程关闭的对象只能由一个线程拥有,并且该对象包含在该线程中,并且只能由该线程修改.
2)只读共享: 没有其他同步,共享的只读对象可以由多个线程同时访问,但是没有线程可以对其进行修改. 共享的只读对象包括不可变对象和事实不可变对象(在技术上是可变的,但是它们的状态在发布后不会更改).
3)线程安全共享. 线程安全对象在内部进行了同步,因此可以通过对象的公共接口访问多个线程,而无需进一步同步.
4)保护对象. 只能通过持有对象的锁来访问受保护的对象. 受保护的对象包括封装在其他线程安全对象中的对象,以及已由特定锁发出和保护的对象.
21. 饥饿: 当线程由于无法访问所需资源而无法继续执行时,就会发生饥饿(线程永远等待). 导致饥饿的最常见资源是CPU时钟周期. 例如,线程的优先级. 线程API中定义的线程优先级仅用作线程调度的参考. 程API中定义了十个优先级,并且JVM根据需要将它们映射到操作系统的调度优先级. 此映射是特定于平台的,因此在某些操作系统中,可以将两个不同的Java优先级映射到相同的优先级,而在另一个操作系统中,则可以映射到另一个不同的优先级.
提高线程的优先级时,它可能不会发挥任何作用,或者可能使线程的调度优先级高于其他线程,从而导致饥饿.
通常,我们尝试不更改线程的优先级. 只要更改了线程的优先级,程序的行为就将依赖于平台,并会导致出现饥饿的风险.
事务T1阻塞数据R,事务T2请求阻塞R,因此T2等待. T3也请求阻塞R. 当T1释放R上的阻塞时,系统首先批准T3的请求,而T2仍在等待. 然后,T4请求再次阻止R. T3释放R上的块后,系统批准T的请求... T2可能永远等待
22,实时锁定
Livelock是活动性问题的另一种形式. 尽管此问题不会阻塞线程,但它无法继续执行,因为线程将重复执行相同的操作,并且始终会失败. Livelock通常发生在处理事务性消息的应用程序中. 如果无法成功处理消息,则消息处理机制将回滚整个事务并将其放回队列的开头. 尽管处理该消息的线程未被阻止,但是它无法继续执行. 这种形式的活锁通常是由过多的错误恢复代码引起的,因为它错误地将不可修复的错误视为可修复的错误.

当多个协作线程相互响应以修改其各自的状态并使任何一个线程无法继续执行时,就会发生活动锁. 为了解决这个活锁问题,需要在重试机制中引入随机性. 在并发应用程序中,通过等待随机的时间长度和回滚可以有效避免发生活锁.
23. 当争用发生在锁上时,失败争用的线程肯定会阻塞. 当JVM实现阻塞行为时,它可以使用旋转等待(Spin-Waiting,指的是不断尝试通过循环获取锁直到成功),或者通过操作系统挂起被阻塞的线程. 这两种方法的效率取决于上下文切换的成本以及成功获取锁之前等待的时间. 如果等待时间较短,则适合采用自旋等待方法;如果等待时间较长,则宜采用线程挂起方法.
24. 有两个因素会影响对锁进行争用的可能性: 锁请求的频率以及每次持有锁的时间. 如果两者的乘积较小,那么获取锁的大多数操作将不会竞争,因此对锁的竞争不会严重影响可伸缩性. 但是,如果锁上的请求量很高,则需要获取锁的线程将被阻塞并等待. 在极端情况下,即使仍有大量工作等待完成,处理器也会处于空闲状态.
有3种减少锁竞争的方法:
1)减少锁保持时间:
①缩小锁的范围线程安全问题代码,并将与锁无关的代码移出同步代码块,尤其是昂贵的操作和可能被阻止的操作(IO操作).
将一个同步代码块分解为多个同步代码块时,将对性能提高产生负面影响. 分解同步代码块时,理想的平衡点将取决于平台,但实际上,仅当可以从同步代码块中删除一些较大的计算或阻塞操作时,才应考虑同步代码块的大小.
②降低锁的粒度: 锁分解和锁分段
锁分解是使用多个独立锁来保护独立状态变量,从而改变了以前由单个锁保护这些变量的情况. 这些技术可以减少锁定操作的粒度并获得更高的可伸缩性. 但是,使用的锁越多,死锁的风险就越高.
锁分段: 例如,JDK1.7和以前版本的ConcurrentHashMap使用的方法就是分段锁的方法.
2)减少锁定请求的频率
3)将排他锁与协调机制结合使用,以实现更高的并发性
例如,读写锁,并发容器等.
——————————————————
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-228276-1.html
送检和抽检完全是两个概念
大发
千玺就像现实版的真人小王子