lock和wait+signal
2019獨角獸企業重金招聘Python工程師標準>>>
lock和wait+signal
在編程中,我們經常使用多線程來提升性能,所以這就涉及到互斥和同步的問題了。而在編程中,我們一般都是通過如下方式來完成多線程的互斥和同步:
- lock | unlock
- signal + wait(timeout)
- join
- sleep
C語言
在Linux C編程中,我們通常使用pthread類庫來完成跨平臺的多線程控制,如下是幾個常用的API:
- pthread_mutex_lock():占有互斥鎖(阻塞操作)
- pthread_mutex_unlock(): 釋放互斥鎖
- pthread_cond_signal(): 喚醒第一個調用pthread_cond_wait()而進入睡眠的線程
- pthread_cond_wait(): 等待條件變量的特殊條件發生
- pthread_cond_timedwait():等待條件變量的特殊條件發生或者timeout
- pthread_join():阻塞當前的線程,直到另外一個線程運行結束
- sleep() : 休眠固定時間,不過這個API是Linux原生提供,不能跨平臺。
注意:**pthread類庫是glibc(絕大多數Linux平臺標準C庫。)的一部分。這些功能都是通過中斷號進入內核來完成的,而非僅僅做了Linux兼容API。**具體可見 glibc-2.23\sysdeps\nacl\nacl-interface-list.h ,聲明wait(timeout)功能中斷號文件。
Java
在Java中,多線程的控制已經是一個統一標準了,一般都是通過Java原生API或者JUC來實現并發控制。這里來說說原生的API:
- synchronized : 實現了lock 和 unlock的功能
- Object#wait : 等待信號發生,并且可以實現超時等待
- Object#notify : 通知信號發生
- Object#notifyAll :通知信號發生
- Thread#join :阻塞當前的線程,直到另外一個線程運行結束
- Thread#sleep : 休眠固定時間
通過這些API,我們基本上能實現Java的多線程并發控制,當然了可以使用最新的JUC并發庫的API。而這些API底層也是可以通過pthread這個C庫來實現。
示例-Timer
Java中Timer的實現原理就是通過 wait 和 notify 以及 synchronized 來實現的:
Timer timer = new Timer(); timer.schedule(new TimerTask() {@Overridepublic void run() {} }, 1000);其實,Timer持有TimerImpl,其實Impl就是一個Thread實現,它一直阻塞等待task的到來,見run代碼:
public void run() {while (true) {TimerTask task;synchronized (this) {// need to check cancelled inside the synchronized blockif (cancelled) {return;}//等待任務if (tasks.isEmpty()) {if (finished) {return;}// no tasks scheduled -- sleep until any task appeartry {//等待任務加入后,會通過notify來通知它可以運行this.wait();} catch (InterruptedException ignored) {}continue;}....if (timeToSleep > 0) {// sleep!try {//延遲執行代碼this.wait(timeToSleep);} catch (InterruptedException ignored) {}continue;}// no sleep is necessary before launching the task...}...try {//具體執行任務task.run();taskCompletedNormally = true;} finally {...}} }可以看到TimerImpl的run代碼會通過wait來阻塞等待任務加入queue,然后通過notify告知它可以運行task。timer#schedule最后會調用TimerImpl#insertTask,具體代碼如下:
private void insertTask(TimerTask newTask) {// callers are synchronizedtasks.insert(newTask);this.notify(); }**所以任務加入隊列后,通過notify來告知阻塞在等待任務的線程(TimerImpl#run)。**這樣子就實現了Timer的功能了,并且通過wait(timeout)實現了delay的功能。
總結
多線程的控制,其實大多都是依賴:
- lock
- signal + wait
這兩種類型的API來完成并發控制。
而在此基礎上,我們可以實現各種各樣的多線程并發控制,比如說:MQ,CountDownLatch等。
轉載于:https://my.oschina.net/darkgem/blog/660784
總結
以上是生活随笔為你收集整理的lock和wait+signal的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 红楼梦任选人物读后感
- 下一篇: 发朋友圈赞美妈妈的句子211个
