java多線程&&Jmeter壓測實現

來源:互聯網
上載者:User

標籤:jmeter源碼   多線程   安全執行緒   java   

筆者最近在看jmeter源碼,對多執行緒部分的瞭解記錄如下。

Part1 線程與多線程概念


提到線程先來看一下進程(線程的容器)的概念,進程是一個具有獨立功能的程式關於某個資料集合的一次運行活動。它可以申請和擁有系統資源,是一個動態概念,是一個活動的實體。它不只是程式的代碼,還包括當前的活動,通過程式計數器的值和處理寄存器的內容來表示。

對於jmeter來說,運行中的jmeter程式執行個體便是一個進程。而該進程中會包含大量線程。

線程是程式執行流的最小單位,是一組命令的集合。在jmeter中一個線程可以用來執行一個測試案例。在起停等基本屬性設定的基礎上,線程運行時會根據testtree解析出的sample取樣器按需執行流程中包含的測試請求。

不同的資料中對線程狀態有不完全相同的描述,基本上分為五種狀態:建立 開始(等待) 運行 掛起 和 停止。

在jmeter/壓測寶中,需要有高並發性,大量的線程並存執行,其中每個線程代表一個VU。這就涉及到多線程的概念。

對於多線程,在java中有兩種實現方式,即,一種是通過繼承thread類;另一種是實現Runnable介面。由於java單繼承機制,繼承thread實現有更多的局限性,一般採用Runnable介面方式。同時,實現了Runnable介面的類,可以通過thread類構造方法public Thread(Runnable target) 來轉化運行。

Jmeter中線程的實現也是採用了Runnable介面方式。

並發大量線程執行相同任務,需要統一管理配置多線程的狀態,便需要引入線程組(threadgroup)的概念。

<Ps:實現Runnable介面比繼承Thread類所具有的優勢:

1):適合多個相同的程式碼的線程去處理同一個資源

2):可以避免java中的單繼承的限制

3):增加程式的健壯性,代碼可以被多個線程共用,代碼和資料獨立。>

 

Part2:線程組

Java中有threadgroup的概念,ThreadGroup是一個類,它的目的是提供關於線程組的資訊。ThreadGroup API比較薄弱,它並沒有比Thread提供了更多的功能。它有兩個主要的功能:一是擷取線程組中處於活躍狀態線程的列表;二是為線程設定捕獲異常處理器。

而這薄弱的API不能滿足JMeter的需求,所以JMeter是自訂的threadgroup類。用來實現對一組線程(也就是一個測試執行個體的並發線程)的管理。它針對線程組的各項屬性,如線程的延時啟動時間/開始時間/結束時間/線程總數/正在啟動並執行線程數/線程啟動時間間隔進行設定。當有線程延時啟動時,先建立等量守護線程,由守護線程根據時間建立對應的使用者線程並依次啟動;沒有延時啟動時,直接建立使用者線程並依次啟動。

另外,線程組提供scheduleThread(This will schedule the time for the JMeterThread.),對線程啟動進行時間安排;並能夠控制線程的相關方法:啟動 暫停 停止 等待停止線程, 擷取活動的線程數等。

 上面提到,實現runnable介面的方式適合多個相同的程式碼的線程去處理同一個資源。多線程共用資源便容易引起安全執行緒問題。

 

Part3:安全執行緒

安全執行緒問題產生原理:

線程的工作原理,jvm有一個main   memory,而每個線程有自己的working   memory,一個線程對一個variable進行操作時,都要在自己的working   memory裡面建立一個copy,操作完之後再寫入main   memory。多個線程同時操作同一個variable,就可能會出現不可預知的結果。

比如,兩個線程同時為一個數組添加項,當前數組長度為0.兩個線程同時對其操作,會分別在自己的工作記憶體中拷貝一份進行添加。兩線程分別添加完返回,此時數組長度已經是2,但是每個線程返回的數組長度依然是1,這就引發了問題。

Jmeter中保證安全執行緒的方式:

一)在start方法執行之前定義好線程內部的變數;

Eg :

啟動時間 終止時間等參數是通過第一種賦值,如下jmeter源碼描述:

The following variables are set by StandardJMeterEngine.

This is done before start() is called, so the values will be published to the thread safely

線程的變數是在start方法執行之前,這樣保證變數的作用範圍僅限於線程內。

二)用volatile關鍵字來標識線程共用的變數(PS:當我們使用volatile關鍵字去修飾變數的時候,所以線程都會直接讀取該變數並且不緩衝它);

     Eg:

線程共用的變數如running /onErrorStopTest等是採用volatile關鍵字。

 

 

三)通過synchronized同步代碼塊或方法體(PS:用synchronized的關鍵是建立一個monitor,這個monitor可以是要修改的variable也可以其他你認為合適的object比如method,然後通過給這個monitor加鎖來實現安全執行緒,每個線程在獲得這個鎖之後,要執行完  從mainmemory  load到workingmemory   ->   use&assign   ->   store到mainmemory   的過程,才會釋放它得到的鎖。這樣就實現了所謂的安全執行緒。);

    Eg:

對於方法/代碼塊,如 static synchronized void incrNumberOfThreads()新增活動線程方法等,多線程共用的代碼,需要用synchronized 進行同步。


筆者對多線程瞭解尚淺,文中不當之處敬請指正,萬分感謝!

java多線程&&Jmeter壓測實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.