枚舉線程源碼
1. 請高手幫忙解釋下這多線程的源代碼,每句注釋下 #include <stdio.h> #include <stdlib.h>
首先這是一個生產者和消費者問題。
生產者procer負責產生數據,然後通過put操作將數據放到緩沖區buf中。
消費者consumer負責顯示數據,通過get操作從緩沖區buf中讀取數據。
========》
先看主函數main(),
生產者和消費者分別用兩個線程來實現。
主函數中的pthread_create()函數就是用來創建這兩個線程的。
開始定義了兩個變數th_a,th_b用來記錄這兩個線程的線程號。
線程的程序體分別是procer,consumer。
接下來的pthread_join用來等待兩個線程結束。因為如果不等待,main函數的主線程會立即結束,而兩個子線程還來不及完全執行。
=======》
下面來分別看procer,consumer這兩個線程。
procer循環一百次,每次調用put往buffer中放數據,最後放一個OVER;
consumer循環用get從buffer中讀到數據並列印,直到讀取的數據位OVER數據時結束。
=======》
我們再分別來看put操作和get操作。
由於put和get都要訪問buf,buf就是一個臨界資源,為了解決這個臨界資源,在使用buf之前,要對它加鎖。
pthread_mutex_lock(b->lock)一個為信號量加鎖的函數。每個信號量只能加鎖一次(我說的可能不準確),如果執行該函數的時候,參數中的信號量已經被加鎖,則該函數阻塞,直到信號量被解鎖才繼續執行。這樣就能保證信號量所保護的臨界資源能夠被互斥的訪問。
structprodcons{
intbuffer[BUFFER_SIZE];/*這個就是循環緩沖區*/
pthread_mutex_tlock;/*這個是信號量,用來保證對緩沖區的互斥訪問*/
intreadpos,writepos;/*這兩個成員分別表示讀位置和寫位置*/
pthread_cond_tnotempty;/*這是表示緩沖區「非空」的條件信號量*/
pthread_cond_tnotfull;/*這是表示緩沖區「非滿」的條件信號量*/
};
buf是一個循環的緩沖區,我們先來看緩沖區為空和滿這兩種狀態時,讀、寫標記(readpos,writepos)的位置。
緩沖區為空時,readpos和writepos指在同一位置;
換從去為滿時,writepos位置的下一個位置就是readpos。
/*put負責把數據放到緩沖區*/
voidput(structprodcons*b,intdata)
{
//首先對互斥信號量進行加鎖
pthread_mutex_lock(&b->lock);
/*這里就是判斷緩沖區有沒有滿,用writepos+1與readpos比較,可以參考附圖。
*因為是循環緩沖區,所以要模BUFFER_SIZE。
*如果緩沖區滿,將在while中等待,直到緩沖區非滿,再繼續執行。
*/
while((b->writepos+1)%BUFFER_SIZE==b->readpos){
printf("waitfornotfull ");
//如果已經滿了,則等待消費者讀取了數據後發出「非滿」信號。
pthread_cond_wait(&b->notfull,&b->lock);
}
/*當緩沖區非滿時,將數據寫入緩沖區中writepos對應的位置*/
b->buffer[b->writepos]=data;
//更新writepos到下一個位置
b->writepos++;
//循環利用緩沖區空間,如果超過了最大值,則從頭開始。
if(b->writepos>=BUFFER_SIZE)b->writepos=0;
/*向消費者發送信號,告訴消費者緩沖取非空*/
pthread_cond_signal(&b->notempty);
//對互斥信號進行解鎖。
pthread_mutex_unlock(&b->lock);
}
/*--------------------------------------------------------*/
/*get負責從緩沖區中讀取數據*/
intget(structprodcons*b)
{
intdata;
//對互斥信號量進行加鎖
pthread_mutex_lock(&b->lock);
/*判斷緩沖區是否為空,為空則等待*/
while(b->writepos==b->readpos){
printf("waitfornotempty ");
pthread_cond_wait(&b->notempty,&b->lock);
}
/*讀取readpos位置的數據*/
data=b->buffer[b->readpos];
//更新readpos到下一個位置。
b->readpos++;
//循環利用緩沖區,回撥指針
if(b->readpos>=BUFFER_SIZE)b->readpos=0;
/*發信號給生產者,緩沖區非滿,可以放數據了*/
pthread_cond_signal(&b->notfull);
//對互斥信號量進行解鎖
pthread_mutex_unlock(&b->lock);
returndata;
}
2. 枚舉的屬性和方法
枚舉在java中是一個類 ,代表著類的一一列舉。要想知道枚舉具體的使用首先要先知道它的具體的 屬性 和 方法 才可以。雖然說我們在實際應用中很少去關注它的屬性和方法,而是更多的關注它的 特性 ,利用它本身的特性去滿足各種有意思的場景。
由於上篇內容講了我們自定義的枚舉其實經過編譯之後,實際繼承的是lang包下的Enum類。雖然我們自定義的枚舉類中可能存在不定義私有屬性的情況,但繼承的Enum類中自身就帶有著兩個屬性,name屬性、和ordinal屬性。Enum類的源碼
name為我們枚舉值的名稱,而ordinal這個詞的意思是「序數」或者說「有順序的」,其實就是序數。我們知道枚舉所代表的就是包含一個以上枚舉值的集合,既然是集合它就是有順序的,而大多數我們使用的時候往往忽略了它的序數這個屬性,似乎忘了枚舉是枚舉這件事了。
枚舉中的序號是根據我們的枚舉中顯示的順序決定的,其實是是語法糖轉換時初始化枚舉值時決定了枚舉值的序數,枚舉中,第一個枚舉值的序數總是小於後面枚舉值的序數,且序數是從0開始的。
接著上面講的序數ordinal,針對序數我們先講枚舉的values()方法。
作為一個枚舉值的集合,所必須要有的操作肯定是遍歷,這也是靜態常量所沒有的支持的。values()其實就是獲取我們枚舉值的數組:
雖然我們自定義的枚舉類是可以使用這個方法的,但繼承的Enum類卻沒有這個方法,其實values()這個方法是很特殊的一個方法,之前說過枚舉是一種語法糖,在它真正編譯後,就會產生values()這個方法,所以我們自定義的枚舉類是可以使用這個方法的,而且values()方法所返回的其實是一個淺拷貝;
前面說到枚舉有兩個屬性,name和ordinal,但實際上枚舉只提供了根據name來獲取具體枚舉值的方法,卻沒有提供根據ordinal來獲取具體枚舉值的方法,但是values()方法也算是另外一種彌補了,根據values()得到的數據再根據ordinal序數獲取具體的枚舉值其實也是一樣的效果。valueOf()方法就是那個根據name獲取具體枚舉值的方法,使用案例:
可選姿勢為兩種,一參和兩參,具體看案例。
3. 典型Java線程池的代碼及其各部分功能介紹
( )根據xml文件來管理線程池的最大最小線程數( )對線程池通過Timer定期掃描以防止線程未激活 ( )通過某一個變數(本程序中是freeThreadCount)來得到空閑線程的數目 一 配置xml(listen xml)是 <?xml version= encoding= UTF ?><config><ConsumeThreadPool><minPools> </minPools><! 線程池最小線程 ><maxPools> </maxPools><! 線程池最大線程 ><checkThreadPeriod> </checkThreadPeriod><! 檢查線程池中線程的周期 分鍾 ></ConsumeThreadPool></config> 二 對於ConsumeThreadPoolPara的javabean: import java io *;public class ConsumeThreadPoolPara implements Serializable{private int minPools;private int maxPools;private int checkThreadPeriod;public int getMinPools(){return minPools;}public int getMaxPools(){return maxPools;}public int getCheckThreadPeriod(){return checkThreadPeriod;}public void setMinPools(int minPools){this minPools = minPools;}public void setMaxPools(int maxPools){this maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod){this checkThreadPeriod = checkThreadPeriod;}public String toString(){return minPools+ + maxPools+ +checkThreadPeriod;}public ConsumeThreadPoolPara() {}public static void main(String[] args) {ConsumeThreadPoolPara consumeThreadPool = new ConsumeThreadPoolPara();}} 三 解析xml程序代碼(生成ConsumeThreadPoolPara) 使用jdom解析 import jdom *;import jdom input SAXBuilder;import java io *;import java util *;public class ParseConfig {static Hashtable Listens = null;static ConnPara connpara = null;static ConsumeThreadPoolPara consumeThreadPoolPara = null;private static String configxml = listen xml ;static{getConsumeThreadPoolPara();//得到消費的線程池的參數}/*** 裝載文檔* @return 返回根結點* @throws JDOMException*/public static Element loadDocument() throws JDOMException{SAXBuilder parser = new SAXBuilder(); // 新建立構造器try {Document document = parser build(configxml);Element root = document getRootElement();return root;}catch(JDOMException e){logger error( listen xml文件格式非法! );throw new JDOMException();}}public static ConsumeThreadPoolPara getConsumeThreadPoolPara(){if(consumeThreadPoolPara ==null){try {Element root = loadDocument();Element consumeThreadPool = root getChild( ConsumeThreadPool );if (consumeThreadPool != null) { //代表有資料庫配置consumeThreadPoolPara = new ConsumeThreadPoolPara();Element minPools = consumeThreadPool getChild( minPools );consumeThreadPoolPara setMinPools(Integer parseInt(minPools getTextTrim()));Element maxPools = consumeThreadPool getChild( maxPools );consumeThreadPoolPara setMaxPools(Integer parseInt(maxPools getTextTrim()));Element checkThreadPeriod = consumeThreadPool getChild( checkThreadPeriod );consumeThreadPoolPara setCheckThreadPeriod(Integer parseInt(checkThreadPeriod getTextTrim()));}}catch (JDOMException e) {}}return consumeThreadPoolPara;}} 四 線程池源代碼 import java util *;/*** <p>Title: 線程池</p>* <p>Description: 採集消費模塊</p>* <p>Copyright: Copyright (c) </p>* <p>Company: </p>* @author 張榮斌* @version */public class ThreadPool {private static int minPools = ; //最小連接池數目private static int maxPools = ; //最大連接池數目private static int checkThreadPeriod = ; //檢查連接池的周期ArrayList m_ThreadList;//工作線程列表LinkedList m_RunList = null;//工作任務列表int totalThread = ;//匯流排程數static int freeThreadCount = ;//未被使用的線程數目private java util Timer timer = null;//定時器static Object o = new Object();static{//先初始化線程池的參數ConsumeThreadPoolPara consumeThreadPoolPara = ParseConfig getConsumeThreadPoolPara();if(consumeThreadPoolPara!=null){minPools = consumeThreadPoolPara getMinPools();maxPools = consumeThreadPoolPara getMaxPools();checkThreadPeriod = consumeThreadPoolPara getCheckThreadPeriod()* * ;}}public void setMinPools(int minPools){this minPools = minPools;}public void setMaxPools(int maxPools){this maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod){this checkThreadPeriod = checkThreadPeriod;}public ThreadPool() {m_ThreadList=new ArrayList();m_RunList=new LinkedList();for(int i= ;i<minPools;i++){WorkerThread temp=new WorkerThread();totalThread = totalThread + ;m_ThreadList add(temp);temp start();try{Thread sleep( );}catch(Exception e){}}timer = new Timer(true);//啟動定時器timer schele(new CheckThreadTask(this) checkThreadPeriod);}/*** 當有一個工作來的時候啟動線程池的線程* 當空閑線程數為 的時候 看匯流排程是否小於最大線程池的數目 就new一個新的線程 否則sleep 直到有空閑線程為止;* 當空閑線程不為 則將任務丟給空閑線程去完成* @param work*/public synchronized void run(String work){if (freeThreadCount == ) {if(totalThread<maxPools){WorkerThread temp = new WorkerThread();totalThread = totalThread + ;m_ThreadList add(temp);temp start();synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}else{while (freeThreadCount == ) {try {Thread sleep( );}catch (InterruptedException e) {}}synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}} else {synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}}/*** 檢查所有的線程的有效性*/public synchronized void checkAllThreads() {Iterator lThreadIterator = erator();while (lThreadIterator hasNext()) { //逐個遍厲WorkerThread lTestThread = (WorkerThread) lThreadIterator next();if (! (lTestThread isAlive())) { //如果處在非活動狀態時lTestThread = new WorkerThread(); //重新生成個線程lTestThread start(); //啟動}}}/*** 列印調試信息*/public void printDebugInfo(){System out println( totalThread= +totalThread);System out println( m_ThreadList size()= +m_ThreadList size());}/**** <p>Title: 工作線程類</p>* @author 張榮斌* @version */class WorkerThread extends Thread{boolean running = true;String work;public void run(){while(running){synchronized(o){freeThreadCount++;}synchronized(m_RunList){while(m_RunList size() == ){try{m_RunList wait();if(!running) return;}catch(InterruptedException e){}< lishixin/Article/program/Java/gj/201311/27379