国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java線程安全與非線程安全解析

Java線程安全與非線程安全解析

2021-01-17 14:13CoolRandy Java教程

這篇文章主要介紹了Java線程安全與非線程安全解析,涉及非線程安全現(xiàn)象模擬以及線程安全的實(shí)現(xiàn)等相關(guān)內(nèi)容,需要的朋友可以參考,一起交流學(xué)習(xí)。

ArrayList和Vector有什么區(qū)別?HashMap和HashTable有什么區(qū)別?StringBuilder和StringBuffer有什么區(qū)別?這些都是Java面試中常見的基礎(chǔ)問題。面對這樣的問題,回答是:ArrayList是非線程安全的,Vector是線程安全的;HashMap是非線程安全的,HashTable是線程安全的;StringBuilder是非線程安全的,StringBuffer是線程安全的。因?yàn)檫@是昨晚剛背的《Java面試題大全》上面寫的。此時(shí)如果繼續(xù)問:什么是線程安全?線程安全和非線程安全有什么區(qū)別?分別在什么情況下使用?這樣一連串的問題,一口老血就噴出來了…

非線程安全的現(xiàn)象模擬

這里就使用ArrayList和Vector二者來說明。

下面的代碼,在主線程中new了一個(gè)非線程安全的ArrayList,然后開1000個(gè)線程分別向這個(gè)ArrayList里面添加元素,每個(gè)線程添加100個(gè)元素,等所有線程執(zhí)行完成后,這個(gè)ArrayList的size應(yīng)該是多少?應(yīng)該是100000個(gè)?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class Main
{
  public static void main(String[] args)
  {
    // 進(jìn)行10次測試
    for(int i = 0; i < 10; i++)
    {
      test();
    }
  }
  public static void test()
  {
    // 用來測試的List
    List<Object> list = new ArrayList<Object>();
    // 線程數(shù)量(1000)
    int threadCount = 1000;
    // 用來讓主線程等待threadCount個(gè)子線程執(zhí)行完畢
    CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    // 啟動(dòng)threadCount個(gè)子線程
    for(int i = 0; i < threadCount; i++)
    {
      Thread thread = new Thread(new MyThread(list, countDownLatch));
      thread.start();
    }
    try
    {
      // 主線程等待所有子線程執(zhí)行完成,再向下執(zhí)行
      countDownLatch.await();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
    // List的size
    System.out.println(list.size());
  }
}
class MyThread implements Runnable
{
  private List<Object> list;
  private CountDownLatch countDownLatch;
  public MyThread(List<Object> list, CountDownLatch countDownLatch)
  {
    this.list = list;
    this.countDownLatch = countDownLatch;
  }
  public void run()
  {
    // 每個(gè)線程向List中添加100個(gè)元素
    for(int i = 0; i < 100; i++)
    {
      list.add(new Object());
    }
    // 完成一個(gè)子線程
    countDownLatch.countDown();
  }
}

上面進(jìn)行了10次測試(為什么要測試10次?因?yàn)榉蔷€程安全并不是每次都會(huì)導(dǎo)致問題)。

輸出結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
99946
100000
100000
100000
99998
99959
100000
99975
100000
99996

上面的輸出結(jié)果發(fā)現(xiàn),并不是每次測試結(jié)果都是100000,有好幾次測試最后ArrayList的size小于100000,甚至?xí)r不時(shí)會(huì)拋出個(gè)IndexOutOfBoundsException異常。(如果沒有這個(gè)現(xiàn)象可以多試幾次)

這就是非線程安全帶來的問題了。上面的代碼如果用于生產(chǎn)環(huán)境,就會(huì)有隱患就會(huì)有BUG了。

再用線程安全的Vector來進(jìn)行測試,上面代碼改變一處,test()方法中

?
1
List<Object> list = new ArrayList<Object>();

改成

?
1
List<Object> list = new Vector<Object>();

再運(yùn)行程序。

輸出結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
100000
100000
100000
100000
100000
100000
100000
100000
100000
100000

再多跑幾次,發(fā)現(xiàn)都是100000,沒有任何問題。因?yàn)閂ector是線程安全的,在多線程操作同一個(gè)Vector對象時(shí),不會(huì)有任何問題。

再換成LinkedList試試,同樣還會(huì)出現(xiàn)ArrayList類似的問題,因?yàn)長inkedList也是非線程安全的。

二者如何取舍

非線程安全是指多線程操作同一個(gè)對象可能會(huì)出現(xiàn)問題。而線程安全則是多線程操作同一個(gè)對象不會(huì)有問題。

線程安全必須要使用很多synchronized關(guān)鍵字來同步控制,所以必然會(huì)導(dǎo)致性能的降低。

所以在使用的時(shí)候,如果是多個(gè)線程操作同一個(gè)對象,那么使用線程安全的Vector;否則,就使用效率更高的ArrayList。

非線程安全!=不安全

有人在使用過程中有一個(gè)不正確的觀點(diǎn):我的程序是多線程的,不能使用ArrayList要使用Vector,這樣才安全。

非線程安全并不是多線程環(huán)境下就不能使用。注意我上面有說到:多線程操作同一個(gè)對象。注意是同一個(gè)對象。比如最上面那個(gè)模擬,就是在主線程中new的一個(gè)ArrayList然后多個(gè)線程操作同一個(gè)ArrayList對象。

如果是每個(gè)線程中new一個(gè)ArrayList,而這個(gè)ArrayList只在這一個(gè)線程中使用,那么肯定是沒問題的。

線程安全的實(shí)現(xiàn)

線程安全是通過線程同步控制來實(shí)現(xiàn)的,也就是synchronized關(guān)鍵字。  

在這里,我用代碼分別實(shí)現(xiàn)了一個(gè)非線程安全的計(jì)數(shù)器和線程安全的計(jì)數(shù)器Counter,并對他們分別進(jìn)行了多線程測試。

非線程安全的計(jì)數(shù)器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
public class Main
{
  public static void main(String[] args)
  {
    // 進(jìn)行10次測試
    for(int i = 0; i < 10; i++)
    {
      test();
    }
  }
  public static void test()
  {
    // 計(jì)數(shù)器
    Counter counter = new Counter();
    // 線程數(shù)量(1000)
    int threadCount = 1000;
    // 用來讓主線程等待threadCount個(gè)子線程執(zhí)行完畢
    CountDownLatch countDownLatch = new CountDownLatch(threadCount);
    // 啟動(dòng)threadCount個(gè)子線程
    for(int i = 0; i < threadCount; i++)
    {
      Thread thread = new Thread(new MyThread(counter, countDownLatch));
      thread.start();
    }
    try
    {
      // 主線程等待所有子線程執(zhí)行完成,再向下執(zhí)行
      countDownLatch.await();
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }
    // 計(jì)數(shù)器的值
    System.out.println(counter.getCount());
  }
}
class MyThread implements Runnable
{
  private Counter counter;
  private CountDownLatch countDownLatch;
  public MyThread(Counter counter, CountDownLatch countDownLatch)
  {
    this.counter = counter;
    this.countDownLatch = countDownLatch;
  }
  public void run()
  {
    // 每個(gè)線程向Counter中進(jìn)行10000次累加
    for(int i = 0; i < 10000; i++)
    {
      counter.addCount();
    }
    // 完成一個(gè)子線程
    countDownLatch.countDown();
  }
}
class Counter
{
  private int count = 0;
  public int getCount()
  {
    return count;
  }
  public void addCount()
  {
    count++;
  }
}

上面的測試代碼中,開啟1000個(gè)線程,每個(gè)線程對計(jì)數(shù)器進(jìn)行10000次累加,最終輸出結(jié)果應(yīng)該是10000000。

但是上面代碼中的Counter未進(jìn)行同步控制,所以非線程安全。

輸出結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
9963727
9973178
9999577
9987650
9988734
9988665
9987820
9990847
9992305
9972233

稍加修改,把Counter改成線程安全的計(jì)數(shù)器:

?
1
2
3
4
5
6
7
8
9
10
11
12
class Counter
{
  private int count = 0;
  public int getCount()
  {
    return count;
  }
  public synchronized void addCount()
  {
    count++;
  }
}

上面只是在addCount()方法中加上了synchronized同步控制,就成為一個(gè)線程安全的計(jì)數(shù)器了。再執(zhí)行程序。

輸出結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000
10000000

總結(jié)

以上就是本文關(guān)于Java線程安全與非線程安全解析的全部內(nèi)容,希望對大家有所幫助。有什么問題可以隨時(shí)留言,歡迎大家交流討論。

原文鏈接:http://www.cnblogs.com/CoolRandy/articles/4093419.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩中文字幕一区二区 | 国产精品中文字幕在线观看 | 亚洲国产精品欧美一二99 | 国产精品一区二区三区四区五区 | 免费成人av片 | www.99re| 久久大陆 | 性免费网站 | 久久只有精品 | 黑人精品| 精品一区国产 | 精品一区二区三区蜜桃 | 日韩精品在线一区 | 奇米在线视频 | 精品成人 | 动漫一区二区三区 | 国产美女av在线 | 欧美日韩一级视频 | 91综合网 | 国产美女www | 亚洲电影天堂在线观看 | 香蕉福利视频 | 欧美精品v国产精品v日韩精品 | 天天爽夜夜爽夜夜爽精品视频 | 中文字幕 在线观看 | 日产精品一区二区三区在线观看 | 国产羞羞视频 | 亚洲精品一区二区 | 国产一级片 | 精精国产xxxx在线视频www | 亚洲伊人久久影院 | 国产成人精品一区二区三区网站观看 | 国内精品视频在线观看 | 91视视频在线观看入口直接观看 | 欧美日韩一区二区三区在线观看 | 天天影视网色香欲综合网无拦截 | 91免费看网站 | 成人二区 | 夜夜夜夜夜操 | 国产精品二区三区 | 久9re热视频这里只有精品 |