日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

淺談java多線程編程

瀏覽:86日期:2022-08-27 13:46:46

一、多線程的優(yōu)缺點

多線程的優(yōu)點:

1)資源利用率更好2)程序設(shè)計在某些情況下更簡單3)程序響應(yīng)更快

多線程的代價:

1)設(shè)計更復(fù)雜雖然有一些多線程應(yīng)用程序比單線程的應(yīng)用程序要簡單,但其他的一般都更復(fù)雜。在多線程訪問共享數(shù)據(jù)的時候,這部分代碼需要特別的注意。線程之間的交互往往非常復(fù)雜。不正確的線程同步產(chǎn)生的錯誤非常難以被發(fā)現(xiàn),并且重現(xiàn)以修復(fù)。

2)上下文切換的開銷當(dāng)CPU從執(zhí)行一個線程切換到執(zhí)行另外一個線程的時候,它需要先存儲當(dāng)前線程的本地的數(shù)據(jù),程序指針等,然后載入另一個線程的本地數(shù)據(jù),程序指針等,最后才開始執(zhí)行。這種切換稱為“上下文切換”(“context switch”)。CPU會在一個上下文中執(zhí)行一個線程,然后切換到另外一個上下文中執(zhí)行另外一個線程。上下文切換并不廉價。如果沒有必要,應(yīng)該減少上下文切換的發(fā)生。

二、創(chuàng)建java多線程

1、創(chuàng)建Thread的子類

創(chuàng)建Thread子類的一個實例并重寫run方法,run方法會在調(diào)用start()方法之后被執(zhí)行。例子如下:

public class MyThread extends Thread { public void run(){ System.out.println('MyThread running'); }}MyThread myThread = new MyThread();myTread.start();

也可以如下創(chuàng)建一個Thread的匿名子類:

Thread thread = new Thread(){ public void run(){ System.out.println('Thread Running'); }};thread.start();

2、實現(xiàn)Runnable接口

第二種編寫線程執(zhí)行代碼的方式是新建一個實現(xiàn)了java.lang.Runnable接口的類的實例,實例中的方法可以被線程調(diào)用。下面給出例子:

public class MyRunnable implements Runnable { public void run(){ System.out.println('MyRunnable running'); }}Thread thread = new Thread(new MyRunnable());thread.start();

同樣,也可以創(chuàng)建一個實現(xiàn)了Runnable接口的匿名類,如下所示:

Runnable myRunnable = new Runnable(){ public void run(){ System.out.println('Runnable running'); }}Thread thread = new Thread(myRunnable);thread.start();

三、線程安全

在同一程序中運行多個線程本身不會導(dǎo)致問題,問題在于多個線程訪問了相同的資源。如同一內(nèi)存區(qū)(變量,數(shù)組,或?qū)ο螅⑾到y(tǒng)(數(shù)據(jù)庫,web services等)或文件。實際上,這些問題只有在一或多個線程向這些資源做了寫操作時才有可能發(fā)生,只要資源沒有發(fā)生變化,多個線程讀取相同的資源就是安全的。

當(dāng)兩個線程競爭同一資源時,如果對資源的訪問順序敏感,就稱存在競態(tài)條件。導(dǎo)致競態(tài)條件發(fā)生的代碼區(qū)稱作臨界區(qū)。

如果一個資源的創(chuàng)建,使用,銷毀都在同一個線程內(nèi)完成,且永遠不會脫離該線程的控制,則該資源的使用就是線程安全的。

四、java同步塊

Java中的同步塊用synchronized標(biāo)記。同步塊在Java中是同步在某個對象上。所有同步在一個對象上的同步塊在同時只能被一個線程進入并執(zhí)行操作。所有其他等待進入該同步塊的線程將被阻塞,直到執(zhí)行該同步塊中的線程退出。

有四種不同的同步塊:

實例方法 靜態(tài)方法 實例方法中的同步塊 靜態(tài)方法中的同步塊

實例方法同步:

public synchronized void add(int value){this.count += value; }

Java實例方法同步是同步在擁有該方法的對象上。這樣,每個實例其方法同步都同步在不同的對象上,即該方法所屬的實例。只有一個線程能夠在實例方法同步塊中運行。如果有多個實例存在,那么一個線程一次可以在一個實例同步塊中執(zhí)行操作。一個實例一個線程。

靜態(tài)方法同步:

public static synchronized void add(int value){ count += value; }

靜態(tài)方法的同步是指同步在該方法所在的類對象上。因為在Java虛擬機中一個類只能對應(yīng)一個類對象,所以同時只允許一個線程執(zhí)行同一個類中的靜態(tài)同步方法。

實例方法中的同步塊:

public void add(int value){ synchronized(this){ this.count += value; } }

注意Java同步塊構(gòu)造器用括號將對象括起來。在上例中,使用了“this”,即為調(diào)用add方法的實例本身。在同步構(gòu)造器中用括號括起來的對象叫做監(jiān)視器對象。上述代碼使用監(jiān)視器對象同步,同步實例方法使用調(diào)用方法本身的實例作為監(jiān)視器對象。一次只有一個線程能夠在同步于同一個監(jiān)視器對象的Java方法內(nèi)執(zhí)行。

下面兩個例子都同步他們所調(diào)用的實例對象上,因此他們在同步的執(zhí)行效果上是等效的。

public class MyClass { public synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public void log2(String msg1, String msg2){ synchronized(this){ log.writeln(msg1); log.writeln(msg2); } } }

靜態(tài)方法中的同步塊:

public class MyClass { public static synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public static void log2(String msg1, String msg2){ synchronized(MyClass.class){ log.writeln(msg1); log.writeln(msg2); } } }

這兩個方法不允許同時被線程訪問。如果第二個同步塊不是同步在MyClass.class這個對象上。那么這兩個方法可以同時被線程訪問。

五、java線程通信

線程通信的目標(biāo)是使線程間能夠互相發(fā)送信號。另一方面,線程通信使線程能夠等待其他線程的信號。

Java有一個內(nèi)建的等待機制來允許線程在等待信號的時候變?yōu)榉沁\行狀態(tài)。java.lang.Object 類定義了三個方法,wait()、notify()和notifyAll()來實現(xiàn)這個等待機制。

一個線程一旦調(diào)用了任意對象的wait()方法,就會變?yōu)榉沁\行狀態(tài),直到另一個線程調(diào)用了同一個對象的notify()方法。為了調(diào)用wait()或者notify(),線程必須先獲得那個對象的鎖。也就是說,線程必須在同步塊里調(diào)用wait()或者notify()。

以下為一個使用了wait()和notify()實現(xiàn)的線程間通信的共享對象:

public class MyWaitNotify{ MonitorObject myMonitorObject = new MonitorObject(); boolean wasSignalled = false; public void doWait(){ synchronized(myMonitorObject){ while(!wasSignalled){ try{ myMonitorObject.wait(); } catch(InterruptedException e){...} } //clear signal and continue running. wasSignalled = false; } } public void doNotify(){ synchronized(myMonitorObject){ wasSignalled = true; myMonitorObject.notify(); } }}

注意以下幾點:

1、不管是等待線程還是喚醒線程都在同步塊里調(diào)用wait()和notify()。這是強制性的!一個線程如果沒有持有對象鎖,將不能調(diào)用wait(),notify()或者notifyAll()。否則,會拋出IllegalMonitorStateException異常。

2、一旦線程調(diào)用了wait()方法,它就釋放了所持有的監(jiān)視器對象上的鎖。這將允許其他線程也可以調(diào)用wait()或者notify()。

3、為了避免丟失信號,必須把它們保存在信號類里。如上面的wasSignalled變量。

4、假喚醒:由于莫名其妙的原因,線程有可能在沒有調(diào)用過notify()和notifyAll()的情況下醒來。這就是所謂的假喚醒(spurious wakeups)。為了防止假喚醒,保存信號的成員變量將在一個while循環(huán)里接受檢查,而不是在if表達式里。這樣的一個while循環(huán)叫做自旋鎖。

5、不要在字符串常量或全局對象中調(diào)用wait()。即上面MonitorObject不能是字符串常量或是全局對象。每一個MyWaitNotify的實例都擁有一個屬于自己的監(jiān)視器對象,而不是在空字符串上調(diào)用wait()/notify()。

六、java中的鎖

自Java 5開始,java.util.concurrent.locks包中包含了一些鎖的實現(xiàn),因此你不用去實現(xiàn)自己的鎖了。

常用的一些鎖:

java.util.concurrent.locks.Lock;java.util.concurrent.locks.ReentrantLock;java.util.concurrent.locks.ReadWriteLock;java.util.concurrent.locks.ReentrantReadWriteLock;

一個可重入鎖(reentrant lock)的簡單實現(xiàn):

public class Lock { boolean isLocked = false; Thread lockedBy = null; int lockedCount = 0; public synchronized void lock() throws InterruptedException{ Thread callingThread = Thread.currentThread(); while(isLocked && lockedBy != callingThread){ wait(); } isLocked = true; lockedCount++; lockedBy = callingThread; } public synchronized void unlock(){ if(Thread.currentThread() == this.lockedBy){ lockedCount--; if(lockedCount == 0){isLocked = false;notify(); } } }}

注意的一點:在finally語句中調(diào)用unlock()

lock.lock();try{ //do critical section code, which may throw exception} finally { lock.unlock();}

七、java中其他同步方法

信號量(Semaphore):java.util.concurrent.Semaphore

阻塞隊列(Blocking Queue):java.util.concurrent.BlockingQueue

public class BlockingQueue { private List queue = new LinkedList(); private int limit = 10; public BlockingQueue(int limit) { this.limit = limit; } public synchronized void enqueue(Object item) throws InterruptedException { while (this.queue.size() == this.limit) { wait(); } if (this.queue.size() == 0) { notifyAll(); } this.queue.add(item); } public synchronized Object dequeue() throws InterruptedException { while (this.queue.size() == 0) { wait(); } if (this.queue.size() == this.limit) { notifyAll(); } return this.queue.remove(0); }}

八、java中的線程池

Java通過Executors提供四種線程池,分別為:

newCachedThreadPool

創(chuàng)建一個可緩存的線程池。如果線程池的大小超過了處理任務(wù)所需要的線程,那么就會回收部分空閑(60秒不執(zhí)行任務(wù))的線程,當(dāng)任務(wù)數(shù)增加時,此線程池又可以智能的添加新線程來處理任務(wù)。此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(tǒng)(或者說JVM)能夠創(chuàng)建的最大線程大小。

newFixedThreadPool

創(chuàng)建固定大小的線程池。每次提交一個任務(wù)就創(chuàng)建一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執(zhí)行異常而結(jié)束,那么線程池會補充一個新線程。

newScheduledThreadPool

創(chuàng)建一個大小無限制的線程池。此線程池支持定時以及周期性執(zhí)行任務(wù)。

newSingleThreadExecutor

創(chuàng)建一個單線程的線程池。此線程池支持定時以及周期性執(zhí)行任務(wù)。這個線程池只有一個線程在工作,也就是相當(dāng)于單線程串行執(zhí)行所有任務(wù)。如果這個唯一的線程因為異常結(jié)束,那么會有一個新的線程來替代它。此線程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行。

線程池簡單用法:

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Main { public static void main(String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int index = i; cachedThreadPool.execute(new Runnable() {public void run() { System.out.println(index);} }); } }}

以上就是淺談java多線程編程的詳細內(nèi)容,更多關(guān)于java多線程的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
理论片午夜视频在线观看| 成人在线观看免费视频| 另类av一区二区| 久久av国产紧身裤| 日韩精品一二三四| 国产精品任我爽爆在线播放 | 99精品视频精品精品视频| 欧美精品国产| 最新国产精品久久久| 亚洲免费成人| 久久五月天小说| 美女av在线免费看| 久久精品系列| 国产精品主播| 国产伦精品一区二区三区千人斩| 久久夜色精品| 石原莉奈在线亚洲三区| 亚洲二区三区不卡| 好看的亚洲午夜视频在线| 高潮一区二区| 国产精品久久久久久久久免费高清 | 日韩欧美国产精品综合嫩v| 久久不见久久见中文字幕免费 | 国产精品22p| 精品黄色一级片| 国产盗摄——sm在线视频| 欧美一区久久| 日本va欧美va精品发布| 日韩在线电影| 欧美日韩一区二区国产| 日韩国产高清在线| 人人爱人人干婷婷丁香亚洲| 久久国产尿小便嘘嘘| 国产伦精品一区二区三区千人斩| 国产情侣久久| 亚洲欧洲美洲av| 亚洲欧美伊人| 四虎精品一区二区免费| 国产精品一级| 夜鲁夜鲁夜鲁视频在线播放| 亚洲精品小说| 国产精品一区二区三区av麻| 免费国产自久久久久三四区久久 | 久久中文在线| 丝袜国产日韩另类美女| 9999国产精品| 国产高清精品二区| 日本一区福利在线| 免费观看久久av| 精品久久久亚洲| 日韩视频不卡| 国产v综合v| 国产精品伦理久久久久久| 欧美一区精品| 日韩不卡在线观看日韩不卡视频| 国产一级久久| 黄色亚洲免费| 亚洲国产成人精品女人| 91成人精品| 极品日韩av| 免费视频亚洲| 国产精品99一区二区| 久久人人88| 日韩欧美综合| 久久久久99| 成人国产精品一区二区免费麻豆| 欧美国产亚洲精品| 日韩综合一区| 激情黄产视频在线免费观看| 国产激情在线播放| 色婷婷色综合| 久久精品亚洲人成影院| 欧美精品九九| 日韩精品免费视频一区二区三区| 蜜臀久久99精品久久久久宅男 | 99精品美女| 欧美粗暴jizz性欧美20| 色综合www| 在线视频精品| 日韩高清二区| 国产精品二区不卡| 国产一区清纯| 亚洲乱码久久| 国产精品探花在线观看| 成人午夜在线| 亚洲精品99| 国产精品传媒麻豆hd| 在线亚洲人成| 亚洲一区导航| 精品国产18久久久久久二百| 欧美日韩精品一区二区视频| 亚洲综合福利| 国产精品网址| 伊人精品视频| 麻豆精品视频在线观看免费| 日韩在线综合| 欧美中文一区| 日韩亚洲国产欧美| 福利视频一区| 日韩高清在线观看一区二区| 另类中文字幕国产精品| 欧美日韩夜夜| 亚洲综合国产| 日韩欧美一区二区三区在线视频 | 色黄视频在线观看| 日韩在线a电影| 91精品综合| 久久精品二区亚洲w码| 免费成人性网站| 91精品国产91久久久久久黑人| 日韩精品欧美大片| 宅男噜噜噜66国产日韩在线观看| 开心激情综合| 国产精品激情| 免费看黄色91| 伊人久久成人| 天堂资源在线亚洲| 国产白浆在线免费观看| 日本h片久久| 天堂久久一区| 日日摸夜夜添夜夜添国产精品| 精品1区2区3区4区| 久久中文字幕av| 久久人人99| 999国产精品| a日韩av网址| 97在线精品| 日本美女一区| 欧美丰满日韩| 欧美片第1页| 91精品蜜臀一区二区三区在线| 精品91福利视频| 国产精品国产三级国产在线观看| 日本a口亚洲| 国产欧美一区二区三区精品观看 | 精品九九久久| 午夜影院一区| 九九综合九九| 蜜臀av性久久久久蜜臀aⅴ流畅 | 男女精品网站| 日本亚州欧洲精品不卡| 亚洲+小说+欧美+激情+另类| 日韩高清在线一区| 久久99蜜桃| 国产精品亚洲一区二区三区在线观看| 欧美aa在线观看| 久久亚洲精品伦理| 欧美另类中文字幕| 久久久久久久欧美精品| 日产精品一区二区| 黄色aa久久| 石原莉奈在线亚洲二区| 日韩国产欧美三级| 麻豆网站免费在线观看| 国产一区91| 国产欧美三级| 久久久久国产一区二区| 国产农村妇女精品一区二区| 综合激情网...| 国产高潮在线| 亚洲免费一区二区| 国产欧美成人| 激情婷婷综合| 国产日韩欧美一区二区三区 | 国产精品s色| 99riav1国产精品视频| 日韩av中文字幕一区| 国产精品天天看天天狠| 欧美特黄一级| 国产伊人久久| 日韩av中文字幕一区二区| 日本h片久久| 精品九九在线| 国产精品av一区二区| 国产精品66| 亚洲一区二区三区免费在线观看 | 99成人在线视频| 久久国产精品美女| 色婷婷成人网| 久久不射中文字幕| 久久久久国产一区二区| 国产精品流白浆在线观看| 少妇精品久久久一区二区| 欧美久久天堂| 欧美国产不卡| 久久精品97| 欧美在线看片| 欧美日韩午夜| 久久国产精品免费一区二区三区| 一区二区三区四区精品视频| 亚洲精品国产嫩草在线观看| 欧美极品中文字幕| 国产精品久久久久久久久久妞妞| 婷婷成人av| 日韩精品久久久久久| 丝袜诱惑制服诱惑色一区在线观看| 久久精品动漫| 亚洲爱爱视频| 在线天堂中文资源最新版| 亚洲深夜视频|