java并发编程实践(1)intro

【0】README
0.1)本文部分文字描述转自“java并发编程实践”,旨在学习“java并发编程实践(1)intro”的相关知识;

【3】线程带来的风险
【3.1】安全性问题
1)intro:在没有充足同步的case下,多个线程的操作执行顺序是不可预测的;
2)看个荔枝:
public class UnsafeSequence
{
 private int value;
 
 public int getNext()
 {
  return value++;
 }
}
对以上代码的分析(Analysis):上述类的问题在于:如果执行时机不对,那么两个线程在调用 getNext方法时会得到相同的值;如下图所示:

对上图的分析(Analysis):
A1)虽然递增运算 value++ 看上去是单个操作,但事实上它包含3个独立的操作:读取value,将value加1,并将计算结果写入value;由于运行时可能将多个线程之间的操作交替执行,因此这两个线程可能同时执行读操作,从而使得他们得到相同的值,并都将这个值加1.结果就是,在不同线程的调用中返回了相同的数值;
A2)上面的交替执行示意图给出的是最糟糕的执行case:目的是为了说明,如果错误地假设程序中的操作将按照某种特定顺序来执行,那么会存在各种可能的危险;
A3)在UnsafeSequence类中说明的是一种常见的并发安全问题,称为竞态条件;因为在刚刚的荔枝中,getValue()方法是否返回唯一值,要取决于运行时对线程中操作的交替执行方式,这并不是我们希望看到的case;(干货——引入竞态条件)

3)由于多个线程要共享相同的内存地址空间,并且是并发运行,因此它们可能会访问或修改其他线程正在使用的变量;
4)当多个线程同时访问和修改相同变量时,将会在串行编程模型中引入非串行因素,而这种非串行性是很难分析的。要使多线程程序的行为可以预测,必须对共享变量的访问操作进行协同,这样才不会在线程之间发生彼此干扰。幸运的是,java 提供了各种同步机制来协同这种访问;(干货——引入对共享变量的协同访问操作)
看个荔枝)线程安全的数值序列生成器
public class SafeSequence {
 private int value;
 
 public synchronized int getNext()
 {
  return value++;
 }
}
【3.2】活跃性问题
1)定义:某件正确的事情最终会发生;
2)安全性的含义是:永远不发生最糟糕的事情,而活跃性则关注与另一个目标,即“某件正确的事情最终会发生”
3)当某个操作无法继续执行下去时,就会发生活跃性问题。在串行程序中,活跃性问题的形式之一是无意中造成的无限循环,从而使得循环之后的代码无法得到执行。
4)线程将带来一些其他活跃性问题:如,如果线程A在等待线程B 释放其特有的资源,而线程B永远都不释放该资源,那么A 就会永久地等待下去;

【3.3】性能问题
1)intro:希望正确的事情尽快发生,讲究的是效率;
2)性能问题包括多个方面:如服务时间过长,响应不灵敏,吞吐率过低,资源消耗过高,或者可伸缩性较低等;
3)线程总会带来某种程度的运行时开销:在多线程程序中,当线程调度器临时挂起活跃线程并转而运行另一个线程时,就会频繁地出现上下文切换操作,这种操作将带来极大的开销,保存和回复执行上下文,丢失局部性,并且CPU 时间将更多地花在线程调度而不是线程运行上;(干货——一个常见的荔枝,当跑hadoop的时候,发现单节点比多节点用的时间还少,就是这个原因,因为不断进行上下文切换,会带来极大的性能开销)

你可能感兴趣的:(java并发编程实践(1)intro)