freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

網(wǎng)絡爬蟲的設計與實現(xiàn)畢業(yè)論文-文庫吧

2025-06-08 02:26 本頁面


【正文】 線程,并指定一個目標。Thread(Runnable target,String name)。創(chuàng)建一個名為 name 的目標為 target 的線程。Thread(String name)。創(chuàng)建一個名為 name 的線程。Thread(ThreadGroup group,Runnable target)。創(chuàng)建一個隸屬于 group 線程組,目標為 target 的線程。通常,我們可以將一個類繼承 Thread,然后,覆蓋 Thread 中的 run()方法,這樣讓這個類本身也就成了線程。每個線程都是通過某個特定 Thread 對象所對應的方法 run()來完成其操作的,方法 run()稱為線程體。使用 start()方法,線程進入 Runnable 狀態(tài),它將線程調(diào)度器注冊這個線程。調(diào)用 start()方法并不一定馬上會執(zhí)行這個線程,正如上面所說,它只是進入Runnble 而不是 Running。 創(chuàng)建線程方式二通過實現(xiàn) Runnable 接口并實現(xiàn)接口中定義的唯一方法 run(),可以創(chuàng)建一個線程。在使用 Runnable 接口時,不能直接創(chuàng)建所需類的對象并運行它,而是必須從 Thread 類的一個實例內(nèi)部運行它。電子科技大學成都學院本科畢業(yè)設計論文4從上面兩種創(chuàng)建線程的方法可以看出,如果繼承 Thread 類,則這個類本身可以調(diào)用 start 方法,也就是說將這個繼承了 Thread 的類當作目標對象;而如果實現(xiàn) Runnable 接口,則這個類必須被當作其他線程的目標對象。 JAVA 中的線程的生命周期JAVA 的線程從產(chǎn)生到消失,可分為 5 種狀態(tài):新建(New),可運行(Runnable),運行( Running),阻塞(Blocked)以及死亡(Dead)。其中,Running 狀態(tài)并非屬于 JAVA 規(guī)范中定義的線程狀態(tài),也就是說,在 JAVA 規(guī)范中,并沒有將運行(Running)狀態(tài)真正的設置為一個狀態(tài),它屬于可運行狀態(tài)的一種。當使用 new 來新建一個線程時,它處于 New 狀態(tài),這個時候,線程并未進行任何操作。然后,調(diào)用線程的 start()方法,來向線程調(diào)度程序(通常是 JVM 或操作系統(tǒng))注冊一個線程,這個時候,這個線程一切就緒,就等待 CPU 時間了。線程調(diào)度程序根據(jù)調(diào)度策略來調(diào)度不同的線程,調(diào)用線程的 run 方法給已經(jīng)注冊的各個線程以執(zhí)行的機會,被調(diào)度執(zhí)行的線程進入運行(Running)狀態(tài)。當線程的 run 方法運行完畢,線程將被拋棄,進入死亡狀態(tài)。你不能調(diào)用 restart方法來重新開始一個處于死亡狀態(tài)的線程,但是,你可以調(diào)用處于死亡狀態(tài)的線程對象的各個方法。如果線程在運行(Running)狀態(tài)中因為 I/O 阻塞,等待鍵盤鍵入,調(diào)用了線程的 sleep 方法,調(diào)用了對象的 wait()方法等,則線程將進入阻塞狀態(tài),直到這些阻塞原因被解除,如:IO 完成,鍵盤輸入了數(shù)據(jù),調(diào)用 sleep 方法后的睡眠時間到以及其他線程調(diào)用了對象的 notify 或 notifyAll 方法來喚醒這個因為等待而阻塞的線程等,線程將返回到 Runnable 狀態(tài)重新等待調(diào)度程序調(diào)度,注意,被阻塞的線程不會直接返回到 Running 狀態(tài),而是重新回到 Runnable 狀態(tài)等待線程調(diào)度程序的調(diào)用。線程調(diào)度程序會根據(jù)調(diào)度情況,將正在運行中的線程設置為 Runnable 狀態(tài),例如,有一個比當前運行狀態(tài)線程更高運行等級的線程進入 Runnable 狀態(tài),就可能將當前運行的線程從 Running 狀態(tài)“踢出”,讓它回到 Runnable 狀態(tài)。 JAVA 線程的結束方式線程會以以下三種方式之一結束:線程到達其 run()方法的末尾;第二章 相關技術介紹5線程拋出一個未捕獲到的 Exception 或 Error;另一個線程調(diào)用一個 Deprecated 的 stop()方法。注意,因為這個方法會引起線程的安全問題,已經(jīng)被不推薦使用了,所以,不要再程序調(diào)用這個方法。 多線程同步當同時運行的相互獨立的線程需要共享數(shù)據(jù)并且需要考慮其他線程的狀態(tài)時,就需要使用一套機制使得這些線程同步,避免在爭用資源時發(fā)生沖突,甚至發(fā)生死鎖。JAVA 提供了多種機制以實現(xiàn)線程同步。多數(shù) JAVA 同步是以對象鎖定為中心的。JAVA 中從 Object 對象繼承來的每個對象都有一個單獨的鎖。由于 JAVA 中的每個對象都是從 Object 繼承來的。所以 JAVA 中的每個對象都有自己的鎖。這樣使它在共享的線程之間可以相互協(xié)調(diào)。在 JAVA 中實現(xiàn)線程同步的另一個方法是通過使用 synchronized 關鍵字。JAVA 使用 synchronized 關鍵字來定義程序中要求線程同步的部分。synchronized 關鍵字實現(xiàn)的基本操作是把每個需要線程同步的部分定義為一個臨界區(qū),在臨界區(qū)中同一時刻只有一個線程被執(zhí)行。 URL 消重 URL 消重的意義在 SPIDER 系統(tǒng)實際運行的過程中,每秒下載的 10 個頁面中,分析的 URL大多數(shù)是重復的,實際上新的 URL 才幾個。在持續(xù)下載的過程中,新的 URL非常少,還是以新浪網(wǎng)舉例,1 天 24 小時中總共出現(xiàn)的新 URL 也就是 10000左右。這種情況非常類似于操作系統(tǒng)中虛擬儲存器管理。所謂的虛擬儲存器,是指具有請求調(diào)入和置換功能,能從邏輯上對內(nèi)存容量加以擴充的一種儲存器系統(tǒng)。其關鍵在于允許一個作業(yè)只裝入部分的頁或段就可以啟動運行,當作業(yè)運行的時候在內(nèi)存中找不到所需要的頁或段的時候,就會發(fā)生請求調(diào)入,而從外存中找到的頁或段將會置換內(nèi)存中暫時不運行的頁面到外存。URL 消重工作量是非常巨大的。以下在新浪新聞頁面為例,新浪一個新聞頁面大小為 50~60k,每個頁面有 90~100 個 URL,如果每秒下載 10 個頁面,就會產(chǎn)生 900~1000 次的 URL 排重操作,每次排重操作都要在幾百萬至幾千萬的 URL 庫中去查詢。這種操作對數(shù)據(jù)庫系統(tǒng)是一個災難,理論上任何需要產(chǎn)生磁盤 I/O 動作的存儲系統(tǒng)都無法滿足這種查詢的需求。 網(wǎng)絡爬蟲 URL 去重儲存庫設計電子科技大學成都學院本科畢業(yè)設計論文6在爬蟲啟動工作的過程中,我們不希望同一個網(wǎng)頁被多次下載,因為重復下載不僅會浪費 CPU 機時,還會為搜索引擎系統(tǒng)增加負荷。而想要控制這種重復性下載問題,就要考慮下載所依據(jù)的超鏈接,只要能夠控制待下載的 URL 不重復,基本可以解決同一個網(wǎng)頁重復下載的問題。非常容易想到,在搜索引擎系統(tǒng)中建立一個全局的專門用來檢測,是否某一個 URL 對應的網(wǎng)頁文件曾經(jīng)被下載過的 URL 存儲庫,這就是方案。接著要考慮的就是如何能夠更加高效地讓爬蟲工作,確切地說,讓去重工作更加高效。如果實現(xiàn)去重,一定是建立一個 URL 存儲庫,并且已經(jīng)下載完成的 URL 在進行檢測時候,要加載到內(nèi)存中,在內(nèi)存中進行檢測一定會比直接從磁盤上讀取速度快很多。我們先從最簡單的情況說起,然后逐步優(yōu)化,最終得到一個非常不錯的解決方案。 基于磁盤的順序存儲這里,就是指把每個已經(jīng)下載過的 URL 進行順序存儲。你可以把全部已經(jīng)下載完成的 URL 存放到磁盤記事本文件中。每次有一個爬蟲線程得到一個任務URL 開始下載之前,通過到磁盤上的該文件中檢索,如果沒有出現(xiàn)過,則將這個新的 URL 寫入記事本的最后一行,否則就放棄該 URL 的下載。這種方式幾乎沒有人考慮使用了,但是這種檢查的思想是非常直觀的。試想,如果已經(jīng)下載了 100 億網(wǎng)頁,那么對應著 100 億個鏈接,也就是這個檢查 URL是否重復的記事本文件就要存儲這 100 億 URL,況且,很多 URL 字符串的長度也不小,占用存儲空間不說,查找效率超級低下,這種方案肯定放棄。 基于 Hash 算法的存儲對每一個給定的 URL,都是用一個已經(jīng)建立好的 Hash 函數(shù),映射到某個物理地址上。當需要進行檢測 URL 是否重復的時候,只需要將這個 URL 進行Hash 映射,如果得到的地址已經(jīng)存在,說明已經(jīng)被下載過,放棄下載,否則,將該 URL 及其 Hash 地址作為鍵值對存放到 Hash 表中。這樣,URL 去重存儲庫就是要維護一個 Hash 表,如果 Hash 函數(shù)設計的不好,在進行映射的時候,發(fā)生碰撞的幾率很大,則再進行碰撞的處理也非常復雜。而且,這里使用的是 URL 作為鍵,URL 字符串也占用了很大的存儲空間。 基于 MD5 壓縮映射的存儲MD5 算法是一種加密算法,同時它也是基于 Hash 的算法。這樣就可以對URL 字符串進行壓縮,得到一個壓縮字符串,同時可以直接得到一個 Hash 地址。另外,MD5 算法能夠?qū)⑷魏巫址畨嚎s為 128 位整數(shù),并映射為物理地址,第二章 相關技術介紹7而且 MD5 進行 Hash 映射碰撞的幾率非常小,這點非常好。從另一個方面來說,非常少的碰撞,對于搜索引擎的爬蟲是可以容忍的。況且,在爬蟲進行檢測的過程中,可以通過記錄日志來保存在進行 MD5 時發(fā)生碰撞的 URL,通過單獨對該 URL 進行處理也是可行的。在 Java 中有一個 Map 類非常好,你可以將壓縮后的 URL 串作為 Key,而將 Boolean 作為 Value 進行存儲,然后將工作中的 Map 在爬蟲停止工作后序列化到本地磁盤上;當下一次啟動新的爬蟲任務的時候,再將這個 Map 反序列化到內(nèi)存中,供爬蟲進行 URL 去重檢測。 基于嵌入式 Berkeley DB 的存儲Berkeley DB 的特點就是只存儲鍵值對類型數(shù)據(jù),這和 URL 去重有很大關系。去重,可以考慮對某個鍵,存在一個值,這個值就是那個鍵的狀態(tài)。使用了 Berkeley DB,你就不需要考慮進行磁盤 IO 操作的性能損失了,這個數(shù)據(jù)庫在設計的時候很好地考慮了這些問題,并且該數(shù)據(jù)庫支持高并發(fā),支持記錄的順序存儲和隨機存儲,是一個不錯的選擇。URL 去重存儲庫使用 Berkeley DB,壓縮后的 URL 字符串作為 Key,或者直接使用壓縮后的 URL 字節(jié)數(shù)組作為 Key,對于 Value 可以使用 Boolean,一個字節(jié),或者使用字節(jié)數(shù)組,實際 Value 只是一個狀態(tài)標識,減少 Value 存儲占用存儲空間。 基于布隆過濾器(Bloom Filter)的存儲使用布隆過濾器,設計多個 Hash 函數(shù),也就是對每個字符串進行映射是經(jīng)過多個 Hash 函數(shù)進行映射,映射到一個二進制向量上,這種方式充分利用了比特位。不過,我沒有用過這種方式,有機會可以嘗試一下??梢詤⒖?Google的 LRU 算法實現(xiàn) URL 消重用雙向鏈表來實現(xiàn)大容量 cache 的 LRU 算法。原理是:cache 的所有位置都用雙向鏈表連接起來,當一個位置被命中后,就將通過調(diào)整鏈表的指向?qū)⒃撐恢谜{(diào)整到鏈表的頭位置,新加入的內(nèi)容直接放在鏈表的頭上。這樣,在進行過多次查找操作后,最近被命中過的內(nèi)容就像鏈表的頭移動,而沒有命中過的內(nèi)容就向鏈表的后面移動。當需要替換時,鏈表最后的位置就是最近最少被命中位置,我們只需要將新的內(nèi)容放在鏈表前面,淘汰鏈表最后的位置就實現(xiàn)了LRU 算法。電子科技大學成都學院本科畢業(yè)設計論文8 URL 類訪問網(wǎng)絡JAVA 提供了許多支 Inter 連接的類,URL 類就是其中之一。在使用URL 類之前,必須創(chuàng)建一個 URL 對象,創(chuàng)建的方法是使用其構造函數(shù),通過向其指定一個 URL 地址,就能實例化該類。如:URL url=new URL( );如果傳遞無效的 URL 給 URL 對象,該對象會拋出 MalformedURLException異常。當成功創(chuàng)建一個 URL 對象后,我們調(diào)用 openConnection 函數(shù)建立與URL 的通信,此時,我們就獲得了一個 URLConnection 對象的引用,URLConnection 類包含了許多與網(wǎng)絡上的 URL 通信的函數(shù)。在下載網(wǎng)頁前,我們需要判斷目標網(wǎng)頁是否存在,這時調(diào)用 URLConnection 類的 getHeaderField()方法,獲得服務器返回給 SPIDER 程序的響應碼,如果響應碼包含”20*”字樣,表示目標網(wǎng)頁存在,下一步就下載網(wǎng)頁,否則就不下載。getHeaderField()方法僅僅獲得服務器返回的頭標志,其通信開銷是最小的,因此在下載網(wǎng)頁前進行此測試,不僅能減小網(wǎng)絡流量,而且能提高程序效率。當目標網(wǎng)頁存在時 2 調(diào)用 URLConnection 類 getInputStream()函數(shù)明確打開到 URL 的連接,獲取輸入流,再用 包中的 InputStreamReader 類讀取該輸入流,將網(wǎng)頁下載下來?!∨佬胁呗詼\析 寬度或深度優(yōu)先搜索策略搜索引擎所用的第一代網(wǎng)絡爬蟲主要是基于傳統(tǒng)的圖算法, 如寬度優(yōu)先或深度優(yōu)先算法來索引整個 Web, 一個核心的 U RL 集被用來作為一個種子集合, 這種算法遞歸的跟蹤超鏈接到其它頁面, 而通常不管頁面的內(nèi)容, 因為最終的目標是這種跟蹤能覆蓋整個 Web. 這種策略通常用在通用搜索引擎中,因為通用搜索引擎獲得的網(wǎng)頁越多越好, 沒有特定的要求. 寬度優(yōu)先搜索算法寬度優(yōu)先搜索算法(又稱廣度優(yōu)先搜索) 是最簡便的圖的搜索算法之一 , 這一算法也是很多重要的圖的算法的原型. Dijkstra 單源最短路徑算法和 Prim 最的寬度遍歷樹的節(jié)點, 如果發(fā)現(xiàn)目標 , 則算法中止 . 該算法的設計和實現(xiàn)相對簡單, 屬于盲目搜索 . 在目前為覆蓋盡可能多的網(wǎng)頁, 一般使用寬度優(yōu)先搜索方法. 第二章 相關技術介紹9也
點擊復制文檔內(nèi)容
外語相關推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1