java 线程---成员变量与局部变量
關(guān)于成員變量與局部變量:
如果一個(gè)變量是成員變量,那么多個(gè)線程對(duì)同一個(gè)對(duì)象的成員變量進(jìn)行操作時(shí),他們對(duì)該成員變量是彼此影響的(也就是說一個(gè)線程對(duì)成員變量的改變會(huì)影響到另一個(gè)線程)?。
?如果一個(gè)變量是局部變量,那么每個(gè)線程都會(huì)有一個(gè)該局部變量的拷貝,一個(gè)線程對(duì)該局部變量的改變不會(huì)影響到其他的線程。?
實(shí)例:
?
Servlet容器為了響應(yīng)多個(gè)用戶同時(shí)訪問一個(gè)Servlet的HTTP請(qǐng)求,通常會(huì)為每個(gè)請(qǐng)求分配一個(gè)工作線程,這些工作線程并發(fā)執(zhí)行同一個(gè)Servlet(即Servlet是單實(shí)例的)的service()方法。此時(shí)可能發(fā)生多線程對(duì)同一數(shù)據(jù)進(jìn)行訪問的情況。
如果多線程并發(fā)訪問,會(huì)訪問同一個(gè)實(shí)例變量,則會(huì)共用name,而出現(xiàn)用戶得到數(shù)據(jù)不一致的現(xiàn)象。
解決辦法:
1.將name設(shè)置為局部變量。
每當(dāng)一個(gè)線程執(zhí)行doPost()時(shí),在線程的堆棧中就會(huì)創(chuàng)建name這個(gè)局部變量,當(dāng)線程執(zhí)行完該方法,局部變量就結(jié)束生命周期。如果多個(gè)線程同時(shí)執(zhí)行該方法,那么每個(gè)線程都擁有自己的局部變量。
2.使用Java同步機(jī)制對(duì)多線程同步
這樣可確保在任意一時(shí)刻,只允許有一個(gè)工作線程執(zhí)行doPost()中的同步代碼塊。只有當(dāng)這個(gè)工作線程退出同步代碼塊時(shí),其他工作線程才允許執(zhí)行同步代碼塊。這使得任意時(shí)刻不會(huì)有兩個(gè)線程同時(shí)操縱同一個(gè)實(shí)例變量,從而避免并發(fā)問題。
3.實(shí)現(xiàn)被廢棄的SingleThreadModel接口
public class Hello extends HttpServlet implements SingleThreadModel{
? ...
}
如果實(shí)現(xiàn)此接口,則Servlet容器實(shí)現(xiàn)可以采用以下兩種方式之一來運(yùn)行Servlet:
1)在任意一時(shí)刻,只允許有一個(gè)工作線程執(zhí)行Servlet的service()方法。如果有多個(gè)用戶同時(shí)請(qǐng)求訪問該Servlet,那么這些客戶請(qǐng)求被 放入等待隊(duì)列,容器會(huì)依次響應(yīng)等待隊(duì)列中的每個(gè)客戶請(qǐng)求。這種實(shí)現(xiàn)方式實(shí)際上禁止了多個(gè)客戶端對(duì)同一個(gè)Servlet的并發(fā)訪問。
2)Servlet容器為每個(gè)Servlet創(chuàng)建一個(gè)對(duì)象池,在這個(gè)池中存放了同一個(gè)Servlet類的多個(gè)實(shí)例。如果有多個(gè)用戶同時(shí)請(qǐng)求訪問該 Servlet,Servlet容器會(huì)為每個(gè)請(qǐng)求分配一個(gè)工作線程,并且從對(duì)象池中取出一個(gè)空閑的Servlet實(shí)例,把它分配給工作線程。每個(gè)工作線程 執(zhí)行自己的Servlet實(shí)例的service()方法。這種實(shí)現(xiàn)方式表面上允許客戶端對(duì)同一個(gè)Servlet并發(fā)訪問,但實(shí)際上不同客戶端訪問的是同一 個(gè)Servlet類的不同實(shí)例。
如果實(shí)例變量需要共享,用以進(jìn)行計(jì)算,這種方法并不能有效的避免并發(fā)問題。?
轉(zhuǎn)載于:https://www.cnblogs.com/kabi/p/5181973.html
總結(jié)
以上是生活随笔為你收集整理的java 线程---成员变量与局部变量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FlashDevelop调试Air出错
- 下一篇: Lucky Substrings