线程学习二
线程学习二
串行、并发、并行
串行
串行如图所示:
串行可以理解为鱼贯而行,任务一个个完成,可以遵循某一原则,但是必须完成前一个任务之后才能完成下一个任务。时间是线性的,即所有程序运行时间之和。
并发
并发如图所示:
并发就是在一段时间内以交替的方式去完成多个任务,可以理解为,cpu内部有一个时间片,然后根据时间片的轮转方式进行工作。
并行
并行如图所示:
并行是齐头并进的方式去完成多个任务。并行是对于多个处理器来说的,因为每一个处理器只能专注于一个任务
对于多线程的是指,就是将任务的处理方式由串行改并发
串行 => 并发
竞态
多线程中有一个普遍的现象,那就是多个线程会去争夺cpu的资源,这种成为竞态。也因此,这可能与时间有关。
- 竞态是指计算的正确性以来于相对时间顺序或者线程的交错
术语:
- 状态变量:类的实例、静态变量(可被多个线程共享,也称为共享变量)
- 共享变量:可以被多个线程同时访问的变量
注意:
竞态不一定就导致计算结果的不正确,它只是不排除计算结果时而正确时而错误的可能
竞态的两种形式
- read-modify-write(读-改-写)
- check-then-act(检测而后行动)
竞态出现的原因往往都是两个或者多个线程,同时读取同一份变量从而导致的。局部变量不会产生这样的问题,因为每个线程访问的都是它们之中的那一份局部变量。依照这个思想,共享变量是否可以做成是唯一的?线程访问共享变量是否应该有先后问题?
竞态的产生往往都是这样的,一个共享变量,一个线程读走了,正准备写入新的数据,又来了一个新的线程,读走了。前一个线程还没有修改完,后一个线程把脏数据读走了,进行了修改,然后再写入。这样导致整个数据都是脏的了。
一个例子,你银行里面存了100块钱,你用ATM机去取钱,在你取钱的那一刹那,你又立即用你的手机进行取钱。如果没有竞态,那么很简单,你只能取到100元。但是如果发生了竞态而不加以任何的改动,你可能会取出200块.....
如果需要解决竞态问题,可以使用
synchronized
关键字。该关键字会使其修饰的方法在任一时刻只能够被一个线程执行。这就可以避免这个方法的交错执行而导致的干扰,消除了竞态。
借鉴:
《Java多线程实战指南》
出自
如需转载,请标明出处