對線程的理解總結

說到線程,我們一定首先想到的是線程的創建,線程的創建一般有兩種方式 一種是實現 Runnable 接口,另一種就是 繼承 Thread 類 ,因爲Java的單繼承多實現機制,所以,優先選擇 實現 Runnable 接口。

 1 package test;
 2 
 3 class ThreadTest extends Thread{
 4 
 5 public void run(){
 6 
 7 System.out.println("實現了Thread類");
 8 
 9 }
10 
11 }
12 
13 class RunnableTest implements Runnable{
14 
15 public void run(){
16 
17 System.out.println("實現了runnable接口");
18 
19 }
20 
21 }
22 
23  
24 
25 public class ThreadStartTest {
26 
27 public static void main(String[] args) {
28 
29 //直接繼承了Thread ,創建一個Thread的實例
30 
31 ThreadTest t1 = new ThreadTest();
32 
33 //t1啓動
34 
35 t1.start();
36 
37 //如果是實現了接口的線程類,需要用對象的實例作爲Thread類構造方法的參數
38 
39 Thread t2 = new Thread(new RunnableTest());
40 
41 t2.start();
42 
43 }
44 
45 }

這兒就有一個我很久之前一直不瞭解的坑。那時因爲不經常使用線程類,所以,對線程的開啓僅停留在有兩種方式上面。在使用繼承的方式時,通過new xxxThread()的方式調用Start()方法,但使用接口的方式時 一直也是new xxxThread()d的方式,發現調不了start()方法,就調用了run()方法。.....其實這樣是不對的,對於Java來說,通過new的方式調用內部run()方法一點問題都沒有,但並不會開啓新線程,那樣做只會使用main線程。。正確的方式爲Thread t2 = new Thread(new RunnableTest()); 然後調用start()方法。

總之一定要調用start()方法的。

1、那線程開啓了就要考慮線程安全了

線程安全,說到底是數據的安全,我可不認識線程是誰,它安不安全,跟我沒有半毛錢的關係。但數據不能不安全。這裏就要提到內存了,因爲,造成數據不安全的就是內存。

對於一個程序來說,就是一個進程,一個線程是其中的一部分。當系統爲進程分配空間的時候,就會有公共空間(堆,公共方法區),和棧等。而造成不安全的就是這塊公共的內存空間。

當一個線程在數據處理的過程中有另一個線程對數據進行了修改,就會造成數據不安全,程序混亂。這樣我們就說這是線程不安全的。

1.1、怎麼解決線程安全問題

解決線程安全問題,就要找到線程到底是怎麼不安全的根本原因。其次安全與不安全是相對的。如果你的系統只有一個線程運行,或同一時間段不可能有兩個線程同時運行。那也就不存在線程安全問題了。

那線程不安全是怎麼造成的呢?

原因一:

“每條線程有自己的工作內存,線程的工作內存中保存了被該線程使用到的變量的主內存副本拷貝,線程對該變量的所有操作都必須在工作內存中進行,而不能直接讀寫主內存中的變量。不同線程之間也無法直接訪問對方工作內存中的變量,線程間變量值的傳遞均需要通過主內存來完成。”

原因二:線程搶奪

根本原因:線程內的關於外部變量的語境,與真實外部語境不一致。

針對這幾個原因,我們來提出解決的方案。

解決方案一:避重就輕

對於原因一中 線程的工作內存中保存了被該線程使用到的變量的主內存副本拷貝,那就不要拷貝,我們所有的方法的參數都使用方法的局部變量,這樣,就不會產生從主內存拷貝的問題。當每一個線程來執行方法的時候,系統都會爲該線程分配一塊屬於自己的棧內存,這樣,每個執行這個方法的線程都會有屬於自己的局部變量,那麼操作自己的局部變量就不會產生安全問題了。

解決方法二:只讀不寫

對於原因一種的對主內存的拷貝,有時候是不能不拷貝的那,我們就要看看能不能只允許它讀取,不允許修改,也就是使用 final 修飾等...,這樣,你只能看看我的數據,不能修改,就不會造成安全問題了。

解決方案三:人手一份

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章