并发(Concurrent)

Posted by Alexander Wang on June 12, 2016

并发(Concurrent)

概念

并发与并行

并发在于“争”,多个线程争一个资源,譬如争用、死锁等问题; 并行在于“分享”,将计算问题拆分,交给多个线程去计算,譬如Map-Reduce。

乐观锁与悲观锁

乐观锁不锁住竞争资源,而是假设无锁,不断的去尝试访问,直到访问成功。 悲观锁是锁住竞争资源,只有获得锁的线程可以访问,其他的都挂起。 乐观锁有CAS算法,譬如Atomic包下的并发,通过调用C最后通过CPU实现CAS,指令级的消耗小;悲观锁有Synchronized,jvm会将没有获得锁的线程挂起,context切换大;轻度中度使用中建议使用非阻塞算法CAS。

死锁( Deadlock)、饥饿( Starvation)和活锁( Livelock)

死锁循环占用,永远循环下去。 饥饿是一直等着,可能因为优先级低或者某个资源一直被其它线程占用着,可能有机会执行。 活锁是两个线程碰到了互相避让,sleep后又撞上了。

死锁

你访问的资源被别人锁了,别人访问的资源被你锁了。你和别人之间可以有中间人,大家一起死锁。 eg:一共有A、B两个资源,你锁了A,他锁了B,他想访问A,你想访问B。

避免死锁

1.按顺序加锁 你锁了A,他必须先获得A的锁才能获得B的锁。

2.加锁时限 其实这本质是一个lease机制,在分布式场景下经常采用的方案。 一般来讲,我们写一个分布式锁一定会加上释放时间。

3.死锁检测 先用一个map或graph记录所有请求、占有锁记录,再用一个线程对占有和请求进行分析,让一些线程释放锁。

使用技巧

使用多线程的原因:一个CPU单位时间只能被一个线程使用,对于多个事件开启的线程,在事件空闲时期让其他事件的线程访问CPU资源。

java:多线程。

python:多进程,一个进程对应一个线程。协程。

JDK的线程优先级不用管。

start()

suspend(), resume(), stop() 不要用

循环判断boolean代替stop()

等待/通知机制替代resume()

Thread.join()等待线程结束

python协程变量

from gevent local import local


Creative Commons License
This work is licensed under a CC A-S 4.0 International License.