Java多線程及其使用(一)

來源:互聯網
上載者:User

標籤:多線程   java   並發   線程   

Java多線程對我來說一直是個進階而且神秘的東西,那麼今天有幸也正好有時間講解一下Java的多線程。

首先線程的概念及定義就不說了

1.建立線程三種方式:1.繼承Thread 2.實現Runnable介面 3.實現Callable介面

繼承Thread

public class FirstThread extends Thread{private int i;public void run(){for(;i<100;i++){System.out.println(getName()+" "+i);}}public static void main(String[] args){for(int i=0; i<100; i++){System.out.println(Thread.currentThread().getName());if(i == 20){new FirstThread().start();new FirstThread().start();}}}}

實現Runnable

public class SecondThread implements Runnable{private int i;public void run(){for(;i<100;i++){System.out.println(Thread.currentThread().getName()+" "+i);}}public static void main(String[] args){for(int i=0; i<100; i++){System.out.println(Thread.currentThread().getName()+" "+i);if(i == 20){SecondThread st = new SecondThread();new Thread(st,"新線程1").start();new Thread(st, "新線程2").start();}}}}

實現Callable

import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;public class ThirdThread implements Callable<Integer>{public Integer call(){int i=0;for(;i<100;i++){System.out.println(Thread.currentThread().getName()+"的迴圈變數i的值"+i);}return i;}public static void main(String[] args){ThirdThread rt = new ThirdThread();FutureTask<Integer> task = new FutureTask<Integer>(rt);for(int i=0; i<100; i++){System.out.println(Thread.currentThread().getName()+"的迴圈變數i的值"+" "+i);if(i==20){new Thread(task, "有傳回值的線程").start();}}try{System.out.println("子線程的傳回值:"+task.get());}catch(Exception e){e.printStackTrace();}}}

簡單說明:Callable更像是Runnable的增強版,所以可以歸為一類,所以大體上建立線程的方式只有兩種,對於使用Thread方式好,還是Runnale方式好,這裡推薦Runnale方法,因為如果採用繼承Thread方法就不能繼承其它父類,相比之下,Runnale則更加靈活

2.線程的生命週期(這裡以網上收集的一幅圖來說明)

3.線程的控制

(1)join()方法:作用是如果在運行當前線程的時候中途你又調用另一線程,那麼當前線程先暫停執行,把另一線程執行完後在繼續執行

(2)守護線程:作用是為其它線程提供服務,而且又在後台運行,所以又叫後台線程

(3)線程睡眠:使用sleep方法,可以理解為在睡眠這段時間內指定的線程都不會執行(就讓它一直睡下去),即在指定時間內的線程無效(這是為了協助理解,片面的說法)

(4)線程讓步:使用yield方法,可以理解為在指定時間內指定的線程不執行,過了這段時間,在執行(只是暫停,目的是為了想讓其它線程執行)

(5)優先順序的設定:字面意思就可以理解,就不再闡述

4.線程的同步(意思就是線程按先後順序依次執行)

試想如果線程不同步,就會出現不按順序執行,就會出現線程同時執行,這樣就會出大問題

如果多個線程非同步(不同步)訪問,就出問題了,比如典型的銀行存款取款問題,這是類似生產者和消費者的問題(其實很簡單,意思就是一個人賺錢一個人花錢),如果存款和取款同時操作,我們就會出現很多問題,比如作為取款方,系統要對取款進行錢的減量操作,但是另一個人又在存,而且同一時間,我的減量操作到底是存了後的還是存了前的?作為存款方,系統對存款進行增量操作,但是我的增量操作,到底是取了後的還是取了錢的,那麼系統就會出問題了,那麼銀行要是這麼搞,你會高興還是悲傷呢,自己的錢老是出問題。

所以,多個線程訪問同樣資源時,我們要進行同步操作,同步操作有以下幾種方式

(1).使用synchronized:可以對方法進行鎖定,可以理解為,每個線程有一把鑰匙,你執行這個方法,方法使用synchronized就會加鎖,你要你的線程只有一個能到達鎖前開鎖,每個線程訪問都會對該方法鎖定;也可以對代碼塊鎖定,大家都知道,函數方法就是代碼寫的,那麼方法能鎖定代碼塊也能鎖定

對方法鎖定

public synchronized void 方法名(鎖定的參數(比如銀行賬戶)){

方法的實現

}

對代碼塊的鎖定

synchronized(鎖定的參數(比如銀行賬戶)){

代碼的實現

}

(2).使用同步鎖Lock:這個方法比synchronized更強大,主要體現在:更為廣泛的鎖定操作,因此實現起來更為靈活,比較好的東西也比較重要,但是使用方法差不多,所以這裡不做詳細介紹

4.2.死結:是指兩個或兩個以上的線程在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去(感覺不是很好理解,可以查閱相關資料)

5線程的通訊,有以下幾種方式

(1)對於synchronized藉助Object類提供的wait(),notify,nitifyAll()三個方法,我們從字面意思就可以大體理解他們的作用

(2)如果使用Lock對象,則要使用Condition來控制,藉助await(),signal,signalAll(),是不是感覺和synchronized的通訊控制比較相似,那麼我們也可以以字面意思來理解它們的大體作業

(3)使用阻塞隊列(BlockingQueue),這是Java5提供的一個介面BlockigQueue,使用put(),take(),方法,

6.線程組,線程池,線程相關的工具ThreadLoacl及安全的線程集合(主要對不安全的集合進行封裝,使之安全)以後再做介紹


最後是線程的使用:

我們學習了線程最為困惑的是什麼時候我們使用多線程:

1.要處理的資料比較龐大(比如對資料庫的資料進行分析)

2.並發控制,一般採用線程池技術

時間不夠了,就暫時寫到這裡吧,寫的不是很詳細,有時間再補充上去,對了,這裡推薦一個網站給大家吧,並發編程網,我感覺裡面的東西非常好,所以有時間一定要去看看,如果你對多線程技術感興趣的話



Java多線程及其使用(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.