即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

线程中的同步和异步

编程语言 qq_32998153 11℃ 0评论

同步:线程按照一定的顺序访问数据,若此时一个线程正在访问此数据,其他的线程若想要也访问此数据,则必须等待,到这个线程访问完了,其他的线程才可以访问,提供了一个安全的方式访问数据。

异步:虽然次线程所请求的资源正在被一个线程使用,但仍然可以访问到这个资源,这就会出现问题,导致结果是不可预测的。

多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 





程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解 





决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲 





系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制 。


这里也涉及到了许多专业术语,其中就有原子操作,所谓原子操作:指如果做,就必须做完,否则就别做,这个操作的步骤是一个整体,不可分割,如一个线程在做这个操作的时候,他既然做这个操作,就必须做完,在此期间别的线程是不会打断他的,别的线程会打断一个正在执行的线程,都是在两个原子操作的间隙打断的,它是不会打断一个原子操作的。

假设a等于1,执行a++,若步骤分为3步,已是读取a的值,执行++操作,然后赋值给a,若此时线程A正在执行读取a操作,当线程A刚好执行完读取a操作后,此时A线程读取到的a值是1,但由于没有实行同步,A线程被B线程打断(你可能察觉不到cpu现在执行的是B线程,你还一直以为cpu一直在执行A线程),现在执行B线程,B线程也是先读取a,再++,后赋值给a,若B线程执行完后,此时a的值已不再是1,而是2,现在由A线程在执行A线程刚才没有执行完的操作,当A执行完所有操作后,此时a的值应该是2,但此时a的值是3,这就是由于a++操作没有实现同步,也是因为a++操作不是原子操作,若a++操作是原子操作,A线程在执行a++操作的时候,就不会被B线程打断,同步的意义也是在某种程度上为一个不是原子操作的步骤,将它包装为原子操作。

还有一个例子:线程C正在执行读取一个文件的操作,但此时另一个线程B也在线程C读取文件的间隙(认为读取文件不是原子操作),线程B修改了此文件的内容,那么当线程B执行完后,线程C读取的就不是最初的那个文件内容了,这多线程并发需要解决的问题,此时同步就可以派上用场了,我们可以为这个读取文件的步骤加上一个锁,谁想要读写文件,谁必须拿到这个锁,谁才可以进去读或修改文件,但锁只有一把,所以当一个线程拿到这个这个锁的时候,,其他的线程想要读写文件,就必须等待,所以这样就避免了上面执行a++操作和读写文件碰到的一个线程正在执行此步骤,但被另一个线程打断(这里打断是指单核cpu的情况,弱如果有多核cpu。则是多个线程同时访问者资源,这也是不允许的)的情况,也确保了结果的一致性(不会出现不可预料的结果)。

我们经常说的并发是指多个线程同时执行,当是单核cpu时,这里同时是指这个线程执行以下,另外一个线程执行一下,交替执行,只不过这世间非常短,我们感受不到,感觉是“同时”至执行的;当多核cpu时,就可以实现同时(真正的同时)了,A线程在执行,B线程也在执行。多线程是并发的前提,如果自始至终程序只有一个线程,那也就无从可谈并发了。

转载请注明:CodingBlog » 线程中的同步和异步

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情