Concurrency(并发),说的简单点就是多个程序的执行流同时执行,其实同时只是我们更直观的说法罢了,因为程序的执行是与时间片的大小相关的,而多个程序之间的交替执行可以提高CPU的利用率,使得我们看起来多个程序好像同时在执行一样,我们将这种现象或者行为称之为并行。不难发现,多个程序交叉执行,在下面我们都以并发而言,那么就会存在资源的竞争问题,而且多个执行流执行的顺序将是无法判断的,这往往会导致原本第一个执行流的结果被第二个执行流接受;或者说第一个执行流已经将数据清空,但第二个执行流拿到的数据确不是空的等等一系列原本在逻辑上应该存在顺序的问题,却在程序的执行上变得无序了,进而引发一些未知的错误。这在购物上是经常见的,尤其是当双十二购物的时候,想想几亿人一同访问同一个站点,加入 A 用户和 B 用户同时提交了 关于 C 商品的订单,但是 C 只有一件了,这时 A 和 B 通过并发执行就可以都拿到 C 的订单,试想想这只是一个很普遍的小问题,这对商家的损害该有多大,所以并发的问题是很严重的,需要我们认真对待。接下来让我们一同进入实验。
1.1 Concurrency(并发)
Web 应用程序可以同时执行很多任务,开发人员经常使用的变量不是线程安全的,线程安全是指一个对象或者类的领域在多线程同时使用的时候总是保持安全有效的状态,它往往可以利用并发错误,精确地在同一时间同一个页面加载同一个用户。因为所有的线程共享同一个的方区,所有的类变量存储在方法区,多个线程试图同时使用相同的类变量。
这个实验大概要求:打开两个浏览器(其实没有必要打开两个浏览器,在同一个浏览器打开同一个页面即可),一个输入用户名 jeff , 一个输入用户名 dave ,如图 1 和 图 2 所示,尽可能快的按下两个按钮,显示的结果却都是 jeff ,如图 3 所示。具体多线程之间是怎样竞争的可以看看操作系统中对线程之间竞争的讲解在这里不再多说了。
图 1
图 2
图 3
1.2 Shoping Cart Concurrency Flaw(购物车并发漏洞)
在这个实验中你的目的是使用较低的价格买下较高价格的商品。同样涉及到线程的并发问题,那么我们就需要开两个页面,第一个页面选择两个廉价的商品,第二个页面选择两个昂贵的商品,如图 4 和图 5 所示,然后在第一个界面中点击 purchase 购买按钮,在第二个页面中点击 update car 按钮,这时以尽快的速度按下第一个页面中的 confirm 确定按钮。我们会发现如图 6 所示的结果。其实就是当我们更新数据的那个线程还没有结束的时候,我们购买的那个线程已经执行结束了,然后再紧接着执行更新数据的那个线程,就会将我们刚刚购买的商品的信息更新掉,进而出现图中的结果。
图 4
图 5
图 6