多個用戶做出同樣的請求,該請求在代碼中調用同一個方法,那么請問服務器是怎么處理的?


 

https://yq.aliyun.com/ask/12165

 

多線程並發的處理,這里指的是服務器端,也就是 Java 的處理,與頁面無關。

首先,當多個請求同時到達服務器時,服務器會分配線程來執行每個請求(如果請求數量太多,能用的線程有限,則會進行排隊)。所以請求和請求之間首先是一個線程隔離的環境。

每個線程都會按照同樣的順序執行同樣的代碼(這里簡單的不考慮分支),在執行代碼的過程中,線程會訪問和操作各種各樣的對象和變量。所以這里就有一個問題:我怎么知道多個線程會不會訪問到同一個對象,或者同一個變量呢?如果這樣的事情發生了,可能會產生什么后果呢?

在詳細解釋這個問題之前,首先需要明確一個簡單的原則:任何對象都可以被任意多個線程訪問,這是代碼的自由性決定的。但更重要的是,我們可以讓對象主動掌控線程對自己的訪問。

最簡單的控制方式就是 synchronized,意即同時只允許一個線程訪問,其它線程必須先等待。當 synchronized 用在方法上時,表示同一時間只允許一個線程執行這個方法。

那么是否意味着服務器上的所有方法都必須是synchronized的呢?不是。當一個方法執行時,所有的變量和參數都會保存在一個叫做堆棧的內存空間,這個內存空間是線程獨享的,所以線程之間不會相互沖突。例如:

public void hello(String name) {

String greetings = "Hello, " + name; System.out.println(greetings);

}
當多個線程執行 hello() 方法時,每個線程都會在自己的堆棧中存放 name 參數和 greetings 變量。其中 greetings 變量是在方法內定義的,一個線程中的 greetings 變量與另一個線程中的 greetings 變量將是完全隔離的,不會相互影響。

堆棧是線程獨享的,但是放入堆棧的內容則未必。像上面的例子,greetings 變量是線程自己創建的,所以其它線程訪問不到,但 name 參數則未必,有可能多個線程在執行這個方法時,收到的 name 參數是同一個對象。這時候如果方法里面要修改這個對象,那就要小心了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM