日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
關(guān)于Java語言中的線程安全問題

Java語言是一種支持多線程的語言,它通過同步(互斥)和協(xié)作(等待和喚醒)來完成。這里聊聊同步。

北京網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),北京網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為北京千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個(gè)售后服務(wù)好的北京做網(wǎng)站的公司定做!

線程不安全主要來自于類變量(靜態(tài)變量)和實(shí)例變量,前者位于方法區(qū)中,后者位于堆中,都是共享區(qū)域。局部變量是沒有這個(gè)問題的,因?yàn)樗诰€程獨(dú)有的棧中。先看下面的例子:

 
 
 
  1. public class Test implements Runnable {  
  2.  
  3.     private int j;  
  4.  
  5.     public Test() {  
  6.     }  
  7.  
  8.     public void testThreadLocal() {  
  9.         System.out.println(Thread.currentThread().getId()  
  10.                 + ":============================= begin");  
  11.         j = 2;  
  12.         System.out.println(Thread.currentThread().getId() + ":" + j);  
  13.         j = 20;  
  14.         System.out.println(":" + j * 3 + ":");   
  15.         System.out.println(Thread.currentThread().getId()  
  16.                 + ":============================= end");  
  17.     }  
  18.  
  19.     public static void main(String[] args) {  
  20.         Test t = new Test();   
  21.         for (int i = 0; i < 3000; i++) {  
  22.             new Thread(t).start();  
  23.         }  
  24.     }  
  25.  
  26.     @Override 
  27.     public void run() {  
  28.         testThreadLocal();  
  29.     }  
  30. }  
  31.  

執(zhí)行這個(gè)類的main方法,會(huì)出現(xiàn)線程不安全的問題。上面藍(lán)色的語句,應(yīng)該打印出:60:,但實(shí)際開了3000個(gè)線程(為了方便出現(xiàn)不安全的現(xiàn)象)后,會(huì)出現(xiàn)下面紅色的:6:

655:============================= end

49:============================= end

:6:

156:============================= end

152:2

:60:

修改main方法,用多個(gè)Test對象,結(jié)果也是一樣。

 
 
 
  1. public static void main(String[] args) {  
  2.         Test t = new Test();   
  3.         for (int i = 0; i < 3000; i++) {  
  4.             new Thread(new Test() ).start();  
  5.         }  
  6.     }  
  7.  

我們保留多個(gè)Test對象的做法,在testThreadLocal方法上加一個(gè)同步關(guān)鍵字。

 
 
 
  1. public synchronized void testThreadLocal() 

結(jié)果沒有用,仍然是不安全的。改成一個(gè)Test對象,這下可以了。原因很簡單,synchronized通過在對象上加鎖來實(shí)現(xiàn)線程安全。當(dāng)使用多個(gè)Test對象時(shí),僅僅在this對象上加鎖是不行的,要在類(在java中,類仍然通過一個(gè)特殊的Class對象來體現(xiàn))上加鎖才行。所以改成:

 
 
 
  1. public void testThreadLocal() {  
  2.         synchronized (this.getClass()) {  
  3.             System.out.println(Thread.currentThread().getId()  
  4.                     + ":============================= begin");  
  5.             j = 2;  
  6.             System.out.println(Thread.currentThread().getId() + ":" + j);  
  7.             j = 20;  
  8.             System.out.println(":" + j * 3 + ":");  
  9.             System.out.println(Thread.currentThread().getId()  
  10.                     + ":============================= end");  
  11.         }   
  12.     }  
  13.  
  14.    
  15.  

這下可以了。我們再看使用類變量的情況,先把synchronized關(guān)鍵字去掉,恢復(fù)到最初的代碼,然后把實(shí)例變量改成類變量。

 
 
 
  1. private int j;  
  2.  
  3. private static int j;  

實(shí)驗(yàn)結(jié)果和使用實(shí)例變量基本相同,***的不同之處在于,我們可以這樣在類上加鎖了,注意,testThreadLocal方法被改成靜態(tài)方法。

 
 
 
  1. public synchronized static void testThreadLocal() {  
  2.  
  3.         System.out.println(Thread.currentThread().getId()  
  4.                 + ":============================= begin");  
  5.         j = 2;  
  6.         System.out.println(Thread.currentThread().getId() + ":" + j);  
  7.         j = 20;  
  8.         System.out.println(":" + j * 3 + ":");  
  9.         System.out.println(Thread.currentThread().getId()  
  10.                 + ":============================= end");  
  11.  
  12.     }  
  13.  

從上面的例子看到,我們使用類變量和實(shí)例變量的時(shí)候,都要非常小心,在多線程的環(huán)境下,很容易出現(xiàn)線程不安全的情況。上面我們還僅僅以基本類型int為例,如果是其他復(fù)雜類型,甚至像long這種在賦值時(shí)要兩次原子操作的基本數(shù)據(jù)類型,線程不安全的情況還要隱秘一些。

編輯推薦】

  1. JSP+JavaBean+Servlet結(jié)構(gòu)工作原理淺析
  2. Servlet頁面跳轉(zhuǎn)實(shí)現(xiàn)方法的區(qū)別
  3. Servlet多線程的相關(guān)問題淺析
  4. Servlet容器之安全多線程問題
  5. JSP Servlet開發(fā)最初那點(diǎn)事

網(wǎng)站題目:關(guān)于Java語言中的線程安全問題
鏈接URL:http://www.5511xx.com/article/cdssdgg.html