强奸久久久久久久|草草浮力在线影院|手机成人无码av|亚洲精品狼友视频|国产国模精品一区|久久成人中文字幕|超碰在线视屏免费|玖玖欧洲一区二区|欧美精品无码一区|日韩无遮一区二区

首頁(yè) > 產(chǎn)品 > 問(wèn)答 > java消息隊(duì)列,java消息隊(duì)列應(yīng)用在哪些場(chǎng)景 具體說(shuō)明下

java消息隊(duì)列,java消息隊(duì)列應(yīng)用在哪些場(chǎng)景 具體說(shuō)明下

來(lái)源:整理 時(shí)間:2025-03-26 01:46:18 編輯:智能門(mén)戶 手機(jī)版

本文目錄一覽

1,java消息隊(duì)列應(yīng)用在哪些場(chǎng)景 具體說(shuō)明下

對(duì)@用心閣 的實(shí)例補(bǔ)充.1.短信發(fā)送.2.日志記錄.3.郵件發(fā)送.4.通知服務(wù).......
簡(jiǎn)單回答:1. 應(yīng)用間異步通訊2. 網(wǎng)絡(luò)上傳送可靠消息3. 應(yīng)用以發(fā)布訂閱模式耦合

java消息隊(duì)列應(yīng)用在哪些場(chǎng)景 具體說(shuō)明下

2,分布式消息隊(duì)列 java 哪個(gè)好

只說(shuō)開(kāi)源的。 作為經(jīng)典的MOM,ActiveMQ還是在企業(yè)應(yīng)用中出場(chǎng)率很高的。 HornetQ跟JBoss綁定在一起,應(yīng)用也很普遍。 畢竟JMS是業(yè)界標(biāo)準(zhǔn)。 不過(guò)如果想嘗鮮,也可以玩一玩Kafka。
消息隊(duì)列就是在完全處理完隊(duì)列中最前面的數(shù)據(jù)之前,其他的數(shù)據(jù)信息會(huì)依次在隊(duì)列中排好隊(duì),然后一個(gè)一個(gè)數(shù)據(jù)去處理 java的消息隊(duì)列用別人寫(xiě)好的插件用就行了,java自帶的sycronization雖然可以實(shí)現(xiàn),但是擴(kuò)展性很差,且使用效率也不行,其他的插件有很多,都是mq,你百度搜索消息隊(duì)列mq 就好了

分布式消息隊(duì)列 java 哪個(gè)好

3,Java開(kāi)發(fā)中消息隊(duì)列和rpc框架都是做什么的

一,消息隊(duì)列服務(wù)一般用于設(shè)計(jì)多系統(tǒng)之間的信息傳輸,一般這種傳輸不需要對(duì)方對(duì)數(shù)據(jù)做出回應(yīng)。它最常見(jiàn)的方式是構(gòu)建異步的生產(chǎn)者-消費(fèi)者模式。我們?cè)谙到y(tǒng)開(kāi)發(fā)中,有些業(yè)務(wù)并不需要及時(shí)返回結(jié)果,我們可以把這些操作放到隊(duì)列中,然后另起一個(gè)消費(fèi)者去處理它。比如日志,數(shù)據(jù)庫(kù)異步更新。二,rpc一般是用于服務(wù)器與服務(wù)器進(jìn)程之間通信,這種通信有請(qǐng)求和應(yīng)答。它是建立在底層的socket通信之上的。封裝為rpc之后,更加方便建立通信。就像在同一個(gè)進(jìn)程中調(diào)用對(duì)方的方法一樣。它本地的方法名一般和請(qǐng)求到達(dá)的服務(wù)器的方法名一一對(duì)應(yīng)。這樣可以更好的把模塊劃分。所以它是應(yīng)對(duì)分布式而生的。比如一個(gè)網(wǎng)站,一開(kāi)始可能所有的服務(wù)在一個(gè)進(jìn)程中,但是隨著業(yè)務(wù)的增長(zhǎng),一個(gè)進(jìn)程處理不過(guò)來(lái),這時(shí)就需要把業(yè)務(wù)拆分成多個(gè),分部到不同的機(jī)器上去。

Java開(kāi)發(fā)中消息隊(duì)列和rpc框架都是做什么的

4,現(xiàn)在最常用的Java消息隊(duì)列中間件是哪個(gè)

ActiveMQ,是Apache出品,最流行的,能力強(qiáng)勁的開(kāi)源消息總線。ActiveMQ 是一個(gè)完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實(shí)現(xiàn),盡管JMS規(guī)范出臺(tái)已經(jīng)是很久的事情了,但是JMS在當(dāng)今的J2EE應(yīng)用中間仍然扮演著特殊的地位。  MetaQ,是一款完全的隊(duì)列模型消息中間件,服務(wù)器使用Java語(yǔ)言編寫(xiě),可在多種軟硬件平臺(tái)上部署??蛻舳酥С諮ava、C++編程語(yǔ)言。單臺(tái)服務(wù)器可支持1萬(wàn)以上個(gè)消息隊(duì)列,通過(guò)擴(kuò)容服務(wù)器,隊(duì)列數(shù)幾乎可任意橫向擴(kuò)展。每個(gè)隊(duì)列都是持久化、長(zhǎng)度無(wú)限(取決于磁盤(pán)空間大小)、并且可從隊(duì)列任意位置開(kāi)始消費(fèi)
現(xiàn)在出來(lái)個(gè)kafka你可以研究下,這個(gè)是異步的,效率賊高!
ActiveMQ,是Apache出品,最流行的,能力強(qiáng)勁的開(kāi)源消息總線。ActiveMQ 是一個(gè)完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實(shí)現(xiàn),盡管JMS規(guī)范出臺(tái)已經(jīng)是很久的事情了,但是JMS在當(dāng)今的J2EE應(yīng)用中間仍然扮演著特殊的地位。MetaQ,是一款完全的隊(duì)列模型消息中間件,服務(wù)器使用Java語(yǔ)言編寫(xiě),可在多種軟硬件平臺(tái)上部署。客戶端支持Java、C++編程語(yǔ)言。單臺(tái)服務(wù)器可支持1萬(wàn)以上個(gè)消息隊(duì)列,通過(guò)擴(kuò)容服務(wù)器,隊(duì)列數(shù)幾乎可任意橫向擴(kuò)展。每個(gè)隊(duì)列都是持久化、長(zhǎng)度無(wú)限(取決于磁盤(pán)空間大?。?、并且可從隊(duì)列任意位置開(kāi)始消費(fèi)
開(kāi)源JMS供應(yīng)商 ActiveMQjbossmq(jboss 4)jboss messaging (jboss 5)RabbitMQjoram-4.3.21 2006-09-22openjms-0.7.7-alpha-3.zip December 26,2005mantamqubermqSomnifugiJMS 2005-7-27ActiveMQ是Apache的項(xiàng)目,應(yīng)用應(yīng)該要多一些

5,到底什么是消息隊(duì)列Java中如何實(shí)現(xiàn)消息隊(duì)列

“消息隊(duì)列”是在消息的傳輸過(guò)程中保存消息的容器。和我們學(xué)過(guò)的LinkedHashMap,TreeSet等一樣,都是容器。既然是容器,就有有自己的特性,就像LinkedHashMap是以鍵值對(duì)存儲(chǔ)。存取順序不變。而消息隊(duì)列,看到隊(duì)列就可以知道。這個(gè)容器里面的消息是站好隊(duì)的,一般遵從先進(jìn)先出原則。java中已經(jīng)為我們封裝好了很多的消息隊(duì)列。在java 1.5版本時(shí)推出的java.util.concurrent中有很多現(xiàn)成的隊(duì)列供我們使用。特性繁多,種類齊全。是你居家旅游開(kāi)發(fā)必備QAQ。下面簡(jiǎn)單列舉這個(gè)包中的消息隊(duì)列1. :阻塞隊(duì)列 BlockingQueue2. 數(shù)組阻塞隊(duì)列 ArrayBlockingQueue3. 延遲隊(duì)列 DelayQueue4. 鏈阻塞隊(duì)列 LinkedBlockingQueue5. 具有優(yōu)先級(jí)的阻塞隊(duì)列 PriorityBlockingQueue6. 同步隊(duì)列 SynchronousQueue7. 阻塞雙端隊(duì)列 BlockingDeque8. 鏈阻塞雙端隊(duì)列 LinkedBlockingDeque不同的隊(duì)列不同的特性決定了隊(duì)列使用的時(shí)機(jī),感興趣的話你可以詳細(xì)了解。具體的使用方式我就不贅述了
消息隊(duì)列,顧名思義 首先是個(gè)隊(duì)列。 隊(duì)列的操作有入隊(duì)和出隊(duì)也就是你有一個(gè)程序在產(chǎn)生內(nèi)容然后入隊(duì)(生產(chǎn)者) 另一個(gè)程序讀取內(nèi)容,內(nèi)容出隊(duì)(消費(fèi)者)這是最最基本的概念。我想你應(yīng)該是缺乏一個(gè)使用場(chǎng)景。當(dāng)你不需要立即獲得結(jié)果,但是并發(fā)量又不能無(wú)限大的時(shí)候,差不多就是你需要使用消息隊(duì)列的時(shí)候。比如你寫(xiě)日志,因?yàn)榭赡芤粋€(gè)客戶端有多個(gè)操作去寫(xiě),又有很多個(gè)客戶端,顯然并發(fā)不能無(wú)窮大,于是你就需要把寫(xiě)日志的請(qǐng)求放入到消息隊(duì)列里,在消費(fèi)者那邊依次把隊(duì)列中產(chǎn)生的日志寫(xiě)到數(shù)據(jù)庫(kù)里。至于怎么實(shí)現(xiàn)消息隊(duì)列,其實(shí)你本身一個(gè)普通的隊(duì)列就行呀~看你需要什么附加功能而已。
消息隊(duì)列就是在完全處理完隊(duì)列中最前面的數(shù)據(jù)之前,其他的數(shù)據(jù)信息會(huì)依次在隊(duì)列中排好隊(duì),然后一個(gè)一個(gè)數(shù)據(jù)去處理java的消息隊(duì)列用別人寫(xiě)好的插件用就行了,java自帶的sycronization雖然可以實(shí)現(xiàn),但是擴(kuò)展性很差,且使用效率也不行,其他的插件有很多,都是MQ,你消息隊(duì)列MQ就好了

6,在JAVA中怎么實(shí)現(xiàn)消息隊(duì)列

java中的消息隊(duì)列消息隊(duì)列是線程間通訊的手段:import java.util.*public class MsgQueue private Vector queue = null; public MsgQueue() queue = new Vector(); } public synchronized void send(Object o) queue.addElement(o); } public synchronized Object recv() if(queue.size()==0) return null; Object o = queue.firstElement(); queue.removeElementAt(0);//or queue[0] = null can also work return o;}}因?yàn)閖ava中是locked by object的所以添加synchronized 就可以用于線程同步鎖定對(duì)象可以作為多線程處理多任務(wù)的存放task的隊(duì)列。他的client包括封裝好的task類以及thread類Java的多線程-線程間的通信2009-08-25 21:581. 線程的幾種狀態(tài)線程有四種狀態(tài),任何一個(gè)線程肯定處于這四種狀態(tài)中的一種:1) 產(chǎn)生(New):線程對(duì)象已經(jīng)產(chǎn)生,但尚未被啟動(dòng),所以無(wú)法執(zhí)行。如通過(guò)new產(chǎn)生了一個(gè)線程對(duì)象后沒(méi)對(duì)它調(diào)用start()函數(shù)之前。2) 可執(zhí)行(Runnable):每個(gè)支持多線程的系統(tǒng)都有一個(gè)排程器,排程器會(huì)從線程池中選擇一個(gè)線程并啟動(dòng)它。當(dāng)一個(gè)線程處于可執(zhí)行狀態(tài)時(shí),表示它可能正處于線程池中等待排排程器啟動(dòng)它;也可能它已正在執(zhí)行。如執(zhí)行了一個(gè)線程對(duì)象的start()方法后,線程就處于可執(zhí)行狀態(tài),但顯而易見(jiàn)的是此時(shí)線程不一定正在執(zhí)行中。3) 死亡(Dead):當(dāng)一個(gè)線程正常結(jié)束,它便處于死亡狀態(tài)。如一個(gè)線程的run()函數(shù)執(zhí)行完畢后線程就進(jìn)入死亡狀態(tài)。4) 停滯(Blocked):當(dāng)一個(gè)線程處于停滯狀態(tài)時(shí),系統(tǒng)排程器就會(huì)忽略它,不對(duì)它進(jìn)行排程。當(dāng)處于停滯狀態(tài)的線程重新回到可執(zhí)行狀態(tài)時(shí),它有可能重新執(zhí)行。如通過(guò)對(duì)一個(gè)線程調(diào)用wait()函數(shù)后,線程就進(jìn)入停滯狀態(tài),只有當(dāng)兩次對(duì)該線程調(diào)用notify或notifyAll后它才能兩次回到可執(zhí)行狀態(tài)。2. class Thread下的常用函數(shù)函數(shù)2.1 suspend()、resume()1) 通過(guò)suspend()函數(shù),可使線程進(jìn)入停滯狀態(tài)。通過(guò)suspend()使線程進(jìn)入停滯狀態(tài)后,除非收到resume()消息,否則該線程不會(huì)變回可執(zhí)行狀態(tài)。2) 當(dāng)調(diào)用suspend()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例11:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()if(shareVar==0)for(int i=0; i<5; i++)shareVar++;if(shareVar==5)this.suspend(); //(1)}}}elseSystem.out.print(Thread.currentThread().getName());System.out.println(" shareVar = " + shareVar);this.resume(); //(2)}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start(); //(5)//t1.start(); //(3)t2.start(); //(4)}}運(yùn)行結(jié)果為:t2 shareVar = 5i. 當(dāng)代碼(5)的t1所產(chǎn)生的線程運(yùn)行到代碼(1)處時(shí),該線程進(jìn)入停滯狀態(tài)。然后排程器從線程池中喚起代碼(4)的t2所產(chǎn)生的線程,此時(shí)shareVar值不為0,所以執(zhí)行else中的語(yǔ)句。ii. 也許你會(huì)問(wèn),那執(zhí)行代碼(2)后為什么不會(huì)使t1進(jìn)入可執(zhí)行狀態(tài)呢?正如前面所說(shuō),t1和t2是兩個(gè)不同對(duì)象的線程,而代碼(1)和(2)都只對(duì)當(dāng)前對(duì)象進(jìn)行操作,所以t1所產(chǎn)生的線程執(zhí)行代碼(1)的結(jié)果是對(duì)象t1的當(dāng)前線程進(jìn)入停滯狀態(tài);而t2所產(chǎn)生的線程執(zhí)行代碼(2)的結(jié)果是把對(duì)象t2中的所有處于停滯狀態(tài)的線程調(diào)回到可執(zhí)行狀態(tài)。iii. 那現(xiàn)在把代碼(4)注釋掉,并去掉代碼(3)的注釋,是不是就能使t1重新回到可執(zhí)行狀態(tài)呢?運(yùn)行結(jié)果是什么也不輸出。為什么會(huì)這樣呢?也許你會(huì)認(rèn)為,當(dāng)代碼(5)所產(chǎn)生的線程執(zhí)行到代碼(1)時(shí),它進(jìn)入停滯狀態(tài);而代碼(3)所產(chǎn)生的線程和代碼(5)所產(chǎn)生的線程是屬于同一個(gè)對(duì)象的,那么就當(dāng)代碼(3)所產(chǎn)生的線程執(zhí)行到代碼(2)時(shí),就可使代碼(5)所產(chǎn)生的線程執(zhí)行回到可執(zhí)行狀態(tài)。但是要清楚,suspend()函數(shù)只是讓當(dāng)前線程進(jìn)入停滯狀態(tài),但并不釋放當(dāng)前線程所獲得的“鎖標(biāo)志”。所以當(dāng)代碼(5)所產(chǎn)生的線程進(jìn)入停滯狀態(tài)時(shí),代碼(3)所產(chǎn)生的線程仍不能啟動(dòng),因?yàn)楫?dāng)前對(duì)象的“鎖標(biāo)志”仍被代碼(5)所產(chǎn)生的線程占有。#p#2.2 sleep()1) sleep ()函數(shù)有一個(gè)參數(shù),通過(guò)參數(shù)可使線程在指定的時(shí)間內(nèi)進(jìn)入停滯狀態(tài),當(dāng)指定的時(shí)間過(guò)后,線程則自動(dòng)進(jìn)入可執(zhí)行狀態(tài)。2) 當(dāng)調(diào)用sleep ()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例12:class TestThreadMethod extends Threadclass TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()for(int i=0; i<3; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);tryThread.sleep(100); //(4)}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();?。?)t1.start();?。?)//t2.start();?。?)}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 0t1 : 1t1 : 2由結(jié)果可證明,雖然在run()中執(zhí)行了sleep(),但是它不會(huì)釋放對(duì)象的“鎖標(biāo)志”,所以除非代碼(1)的線程執(zhí)行完run()函數(shù)并釋放對(duì)象的“鎖標(biāo)志”,否則代碼(2)的線程永遠(yuǎn)不會(huì)執(zhí)行。如果把代碼(2)注釋掉,并去掉代碼(3)的注釋,結(jié)果將變?yōu)椋簍1 : 0t2 : 0t1 : 1t2 : 1t1 : 2t2 : 2由于t1和t2是兩個(gè)對(duì)象的線程,所以當(dāng)線程t1通過(guò)sleep()進(jìn)入停滯時(shí),排程器會(huì)從線程池中調(diào)用其它的可執(zhí)行線程,從而t2線程被啟動(dòng)。例13:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()for(int i=0; i<5; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);tryif(Thread.currentThread().getName().equals("t1"))Thread.sleep(200);elseThread.sleep(100);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();//t1.start();t2.start();}}運(yùn)行結(jié)果為:t1 : 0t2 : 0t2 : 1t1 : 1t2 : 2t2 : 3t1 : 2t2 : 4t1 : 3t1 : 4由于線程t1調(diào)用了sleep(200),而線程t2調(diào)用了sleep(100),所以線程t2處于停滯狀態(tài)的時(shí)間是線程t1的一半,從從結(jié)果反映出來(lái)的就是線程t2打印兩倍次線程t1才打印一次。#p#2.3 yield()1) 通過(guò)yield ()函數(shù),可使線程進(jìn)入可執(zhí)行狀態(tài),排程器從可執(zhí)行狀態(tài)的線程中重新進(jìn)行排程。所以調(diào)用了yield()的函數(shù)也有可能馬上被執(zhí)行。2) 當(dāng)調(diào)用yield ()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例14:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)}public synchronized void run()System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);Thread.yield();}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();t1.start(); //(1)//t2.start();?。?)}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 3t1 : 0t1 : 1t1 : 2t1 : 3從結(jié)果可知調(diào)用yield()時(shí)并不會(huì)釋放對(duì)象的“鎖標(biāo)志”。如果把代碼(1)注釋掉,并去掉代碼(2)的注釋,結(jié)果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3從結(jié)果可知,雖然t1線程調(diào)用了yield(),但它馬上又被執(zhí)行了。2.4 sleep()和yield()的區(qū)別1) sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài),所以執(zhí)行sleep()的線程在指定的時(shí)間內(nèi)肯定不會(huì)執(zhí)行;yield()只是使當(dāng)前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進(jìn)入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。2) sleep()可使優(yōu)先級(jí)低的線程得到執(zhí)行的機(jī)會(huì),當(dāng)然也可以讓同優(yōu)先級(jí)和高優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì);yield()只能使同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。例15:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public void run()for(int i=0; i<4; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);//Thread.yield(); (1)/* (2) */tryThread.sleep(3000);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.setPriority(Thread.MAX_PRIORITY);t2.setPriority(Thread.MIN_PRIORITY);t1.start();t2.start();}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3由結(jié)果可見(jiàn),通過(guò)sleep()可使優(yōu)先級(jí)較低的線程有執(zhí)行的機(jī)會(huì)。注釋掉代碼(2),并去掉代碼(1)的注釋,結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 3t2 : 0t2 : 1t2 : 2t2 : 3可見(jiàn),調(diào)用yield(),不同優(yōu)先級(jí)的線程永遠(yuǎn)不會(huì)得到執(zhí)行機(jī)會(huì)。2.5 join()使調(diào)用join()的線程執(zhí)行完畢后才能執(zhí)行其它線程,在一定意義上,它可以實(shí)現(xiàn)同步的功能。例16:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public void run()for(int i=0; i<4; i++)System.out.println(" " + i);tryThread.sleep(3000);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();tryt1.join();}catch(InterruptedException e)t1.start();}}運(yùn)行結(jié)果為:01230123#p#3. class Object下常用的線程函數(shù)wait()、notify()和notifyAll()這三個(gè)函數(shù)由java.lang.Object類提供,用于協(xié)調(diào)多個(gè)線程對(duì)共享數(shù)據(jù)的存取。3.1 wait()、notify()和notifyAll()1) wait()函數(shù)有兩種形式:第一種形式接受一個(gè)毫秒值,用于在指定時(shí)間長(zhǎng)度內(nèi)暫停線程,使線程進(jìn)入停滯狀態(tài)。第二種形式為不帶參數(shù),代表waite()在notify()或notifyAll()之前會(huì)持續(xù)停滯。2) 當(dāng)對(duì)一個(gè)對(duì)象執(zhí)行notify()時(shí),會(huì)從線程等待池中移走該任意一個(gè)線程,并把它放到鎖標(biāo)志等待池中;當(dāng)對(duì)一個(gè)對(duì)象執(zhí)行notifyAll()時(shí),會(huì)從線程等待池中移走所有該對(duì)象的所有線程,并把它們放到鎖標(biāo)志等待池中。3) 當(dāng)調(diào)用wait()后,線程會(huì)釋放掉它所占有的“鎖標(biāo)志”,從而使線程所在對(duì)象中的其它synchronized數(shù)據(jù)可被別的線程使用。例17:下面,我們將對(duì)例11中的例子進(jìn)行修改class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()if(shareVar==0)for(int i=0; i<10; i++)shareVar++;if(shareVar==5)trythis.wait(); //(4)}catch(InterruptedException e)}}}if(shareVar!=0)System.out.print(Thread.currentThread().getName());System.out.println(" shareVar = " + shareVar);this.notify(); //(5)}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start(); //(1)//t1.start();?。?)t2.start(); //(3)}}運(yùn)行結(jié)果為:t2 shareVar = 5因?yàn)閠1和t2是兩個(gè)不同對(duì)象,所以線程t2調(diào)用代碼(5)不能喚起線程t1。如果去掉代碼(2)的注釋,并注釋掉代碼(3),結(jié)果為:t1 shareVar = 5t1 shareVar = 10這是因?yàn)?,?dāng)代碼(1)的線程執(zhí)行到代碼(4)時(shí),它進(jìn)入停滯狀態(tài),并釋放對(duì)象的鎖狀態(tài)。接著,代碼(2)的線程執(zhí)行run(),由于此時(shí)shareVar值為5,所以執(zhí)行打印語(yǔ)句并調(diào)用代碼(5)使代碼(1)的線程進(jìn)入可執(zhí)行狀態(tài),然后代碼(2)的線程結(jié)束。當(dāng)代碼(1)的線程重新執(zhí)行后,它接著執(zhí)行for()循環(huán)一直到shareVar=10,然后打印shareVar。#p#3.2 wait()、notify()和synchronizedwaite()和notify()因?yàn)闀?huì)對(duì)對(duì)象的“鎖標(biāo)志”進(jìn)行操作,所以它們必須在synchronized函數(shù)或synchronized block中進(jìn)行調(diào)用。如果在non-synchronized函數(shù)或non-synchronized block中進(jìn)行調(diào)用,雖然能編譯通過(guò),但在運(yùn)行時(shí)會(huì)發(fā)生IllegalMonitorStateException的異常。例18:class TestThreadMethod extends Threadpublic int shareVar = 0;public TestThreadMethod(String name)super(name);new Notifier(this);}public synchronized void run()if(shareVar==0)for(int i=0; i<5; i++)shareVar++;System.out.println("i = " + shareVar);trySystem.out.println("wait......");this.wait();}catch(InterruptedException e)}}}}class Notifier extends Threadprivate TestThreadMethod ttm;Notifier(TestThreadMethod t)ttm = t;start();}public void run()while(true)trysleep(2000);}catch(InterruptedException e)/*1 要同步的不是當(dāng)前對(duì)象的做法 */synchronized(ttm)System.out.println("notify......");ttm.notify();}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();}}運(yùn)行結(jié)果為:i = 1wait......notify......i = 2wait......notify......i = 3wait......notify......i = 4wait......notify......i = 5wait......notify......4. wait()、notify()、notifyAll()和suspend()、resume()、sleep()的討論4.1 這兩組函數(shù)的區(qū)別1) wait()使當(dāng)前線程進(jìn)入停滯狀態(tài)時(shí),還會(huì)釋放當(dāng)前線程所占有的“鎖標(biāo)志”,從而使線程對(duì)象中的synchronized資源可被對(duì)象中別的線程使用;而suspend()和sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài)時(shí)不會(huì)釋放當(dāng)前線程所占有的“鎖標(biāo)志”。2) 前一組函數(shù)必須在synchronized函數(shù)或synchronized block中調(diào)用,否則在運(yùn)行時(shí)會(huì)產(chǎn)生錯(cuò)誤;而后一組函數(shù)可以non-synchronized函數(shù)和synchronized block中調(diào)用。4.2 這兩組函數(shù)的取舍Java2已不建議使用后一組函數(shù)。因?yàn)樵谡{(diào)用suspend()時(shí)不會(huì)釋放當(dāng)前線程所取得的“鎖標(biāo)志”,這樣很容易造成“死鎖”。
java中的消息隊(duì)列消息隊(duì)列是線程間通訊的手段:import java.util.*public class MsgQueue private Vector queue = null; public MsgQueue() queue = new Vector(); } public synchronized void send(Object o) queue.addElement(o); } public synchronized Object recv() if(queue.size()==0) return null; Object o = queue.firstElement(); queue.removeElementAt(0);//or queue[0] = null can also work return o;}}因?yàn)閖ava中是locked by object的所以添加synchronized 就可以用于線程同步鎖定對(duì)象可以作為多線程處理多任務(wù)的存放task的隊(duì)列。他的client包括封裝好的task類以及thread類Java的多線程-線程間的通信2009-08-25 21:581. 線程的幾種狀態(tài)線程有四種狀態(tài),任何一個(gè)線程肯定處于這四種狀態(tài)中的一種:1) 產(chǎn)生(New):線程對(duì)象已經(jīng)產(chǎn)生,但尚未被啟動(dòng),所以無(wú)法執(zhí)行。如通過(guò)new產(chǎn)生了一個(gè)線程對(duì)象后沒(méi)對(duì)它調(diào)用start()函數(shù)之前。2) 可執(zhí)行(Runnable):每個(gè)支持多線程的系統(tǒng)都有一個(gè)排程器,排程器會(huì)從線程池中選擇一個(gè)線程并啟動(dòng)它。當(dāng)一個(gè)線程處于可執(zhí)行狀態(tài)時(shí),表示它可能正處于線程池中等待排排程器啟動(dòng)它;也可能它已正在執(zhí)行。如執(zhí)行了一個(gè)線程對(duì)象的start()方法后,線程就處于可執(zhí)行狀態(tài),但顯而易見(jiàn)的是此時(shí)線程不一定正在執(zhí)行中。3) 死亡(Dead):當(dāng)一個(gè)線程正常結(jié)束,它便處于死亡狀態(tài)。如一個(gè)線程的run()函數(shù)執(zhí)行完畢后線程就進(jìn)入死亡狀態(tài)。4) 停滯(Blocked):當(dāng)一個(gè)線程處于停滯狀態(tài)時(shí),系統(tǒng)排程器就會(huì)忽略它,不對(duì)它進(jìn)行排程。當(dāng)處于停滯狀態(tài)的線程重新回到可執(zhí)行狀態(tài)時(shí),它有可能重新執(zhí)行。如通過(guò)對(duì)一個(gè)線程調(diào)用wait()函數(shù)后,線程就進(jìn)入停滯狀態(tài),只有當(dāng)兩次對(duì)該線程調(diào)用notify或notifyAll后它才能兩次回到可執(zhí)行狀態(tài)。2. class Thread下的常用函數(shù)函數(shù)2.1 suspend()、resume()1) 通過(guò)suspend()函數(shù),可使線程進(jìn)入停滯狀態(tài)。通過(guò)suspend()使線程進(jìn)入停滯狀態(tài)后,除非收到resume()消息,否則該線程不會(huì)變回可執(zhí)行狀態(tài)。2) 當(dāng)調(diào)用suspend()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例11:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()if(shareVar==0)for(int i=0; i<5; i++)shareVar++;if(shareVar==5)this.suspend(); //(1)}}}elseSystem.out.print(Thread.currentThread().getName());System.out.println(" shareVar = " + shareVar);this.resume(); //(2)}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start(); //(5)//t1.start(); //(3)t2.start(); //(4)}}運(yùn)行結(jié)果為:t2 shareVar = 5i. 當(dāng)代碼(5)的t1所產(chǎn)生的線程運(yùn)行到代碼(1)處時(shí),該線程進(jìn)入停滯狀態(tài)。然后排程器從線程池中喚起代碼(4)的t2所產(chǎn)生的線程,此時(shí)shareVar值不為0,所以執(zhí)行else中的語(yǔ)句。ii. 也許你會(huì)問(wèn),那執(zhí)行代碼(2)后為什么不會(huì)使t1進(jìn)入可執(zhí)行狀態(tài)呢?正如前面所說(shuō),t1和t2是兩個(gè)不同對(duì)象的線程,而代碼(1)和(2)都只對(duì)當(dāng)前對(duì)象進(jìn)行操作,所以t1所產(chǎn)生的線程執(zhí)行代碼(1)的結(jié)果是對(duì)象t1的當(dāng)前線程進(jìn)入停滯狀態(tài);而t2所產(chǎn)生的線程執(zhí)行代碼(2)的結(jié)果是把對(duì)象t2中的所有處于停滯狀態(tài)的線程調(diào)回到可執(zhí)行狀態(tài)。iii. 那現(xiàn)在把代碼(4)注釋掉,并去掉代碼(3)的注釋,是不是就能使t1重新回到可執(zhí)行狀態(tài)呢?運(yùn)行結(jié)果是什么也不輸出。為什么會(huì)這樣呢?也許你會(huì)認(rèn)為,當(dāng)代碼(5)所產(chǎn)生的線程執(zhí)行到代碼(1)時(shí),它進(jìn)入停滯狀態(tài);而代碼(3)所產(chǎn)生的線程和代碼(5)所產(chǎn)生的線程是屬于同一個(gè)對(duì)象的,那么就當(dāng)代碼(3)所產(chǎn)生的線程執(zhí)行到代碼(2)時(shí),就可使代碼(5)所產(chǎn)生的線程執(zhí)行回到可執(zhí)行狀態(tài)。但是要清楚,suspend()函數(shù)只是讓當(dāng)前線程進(jìn)入停滯狀態(tài),但并不釋放當(dāng)前線程所獲得的“鎖標(biāo)志”。所以當(dāng)代碼(5)所產(chǎn)生的線程進(jìn)入停滯狀態(tài)時(shí),代碼(3)所產(chǎn)生的線程仍不能啟動(dòng),因?yàn)楫?dāng)前對(duì)象的“鎖標(biāo)志”仍被代碼(5)所產(chǎn)生的線程占有。#p#2.2 sleep()1) sleep ()函數(shù)有一個(gè)參數(shù),通過(guò)參數(shù)可使線程在指定的時(shí)間內(nèi)進(jìn)入停滯狀態(tài),當(dāng)指定的時(shí)間過(guò)后,線程則自動(dòng)進(jìn)入可執(zhí)行狀態(tài)。2) 當(dāng)調(diào)用sleep ()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例12:class TestThreadMethod extends Threadclass TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()for(int i=0; i<3; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);tryThread.sleep(100); //(4)}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();?。?)t1.start();?。?)//t2.start(); (3)}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 0t1 : 1t1 : 2由結(jié)果可證明,雖然在run()中執(zhí)行了sleep(),但是它不會(huì)釋放對(duì)象的“鎖標(biāo)志”,所以除非代碼(1)的線程執(zhí)行完run()函數(shù)并釋放對(duì)象的“鎖標(biāo)志”,否則代碼(2)的線程永遠(yuǎn)不會(huì)執(zhí)行。如果把代碼(2)注釋掉,并去掉代碼(3)的注釋,結(jié)果將變?yōu)椋簍1 : 0t2 : 0t1 : 1t2 : 1t1 : 2t2 : 2由于t1和t2是兩個(gè)對(duì)象的線程,所以當(dāng)線程t1通過(guò)sleep()進(jìn)入停滯時(shí),排程器會(huì)從線程池中調(diào)用其它的可執(zhí)行線程,從而t2線程被啟動(dòng)。例13:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()for(int i=0; i<5; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);tryif(Thread.currentThread().getName().equals("t1"))Thread.sleep(200);elseThread.sleep(100);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();//t1.start();t2.start();}}運(yùn)行結(jié)果為:t1 : 0t2 : 0t2 : 1t1 : 1t2 : 2t2 : 3t1 : 2t2 : 4t1 : 3t1 : 4由于線程t1調(diào)用了sleep(200),而線程t2調(diào)用了sleep(100),所以線程t2處于停滯狀態(tài)的時(shí)間是線程t1的一半,從從結(jié)果反映出來(lái)的就是線程t2打印兩倍次線程t1才打印一次。#p#2.3 yield()1) 通過(guò)yield ()函數(shù),可使線程進(jìn)入可執(zhí)行狀態(tài),排程器從可執(zhí)行狀態(tài)的線程中重新進(jìn)行排程。所以調(diào)用了yield()的函數(shù)也有可能馬上被執(zhí)行。2) 當(dāng)調(diào)用yield ()函數(shù)后,線程不會(huì)釋放它的“鎖標(biāo)志”。例14:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)}public synchronized void run()System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);Thread.yield();}}}public class TestThreadTestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start();t1.start(); //(1)//t2.start(); (2)}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 3t1 : 0t1 : 1t1 : 2t1 : 3從結(jié)果可知調(diào)用yield()時(shí)并不會(huì)釋放對(duì)象的“鎖標(biāo)志”。如果把代碼(1)注釋掉,并去掉代碼(2)的注釋,結(jié)果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3從結(jié)果可知,雖然t1線程調(diào)用了yield(),但它馬上又被執(zhí)行了。2.4 sleep()和yield()的區(qū)別1) sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài),所以執(zhí)行sleep()的線程在指定的時(shí)間內(nèi)肯定不會(huì)執(zhí)行;yield()只是使當(dāng)前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進(jìn)入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。2) sleep()可使優(yōu)先級(jí)低的線程得到執(zhí)行的機(jī)會(huì),當(dāng)然也可以讓同優(yōu)先級(jí)和高優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì);yield()只能使同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。例15:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public void run()for(int i=0; i<4; i++)System.out.print(Thread.currentThread().getName());System.out.println(" : " + i);//Thread.yield();?。?)/* (2) */tryThread.sleep(3000);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.setPriority(Thread.MAX_PRIORITY);t2.setPriority(Thread.MIN_PRIORITY);t1.start();t2.start();}}運(yùn)行結(jié)果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3由結(jié)果可見(jiàn),通過(guò)sleep()可使優(yōu)先級(jí)較低的線程有執(zhí)行的機(jī)會(huì)。注釋掉代碼(2),并去掉代碼(1)的注釋,結(jié)果為:t1 : 0t1 : 1t1 : 2t1 : 3t2 : 0t2 : 1t2 : 2t2 : 3可見(jiàn),調(diào)用yield(),不同優(yōu)先級(jí)的線程永遠(yuǎn)不會(huì)得到執(zhí)行機(jī)會(huì)。2.5 join()使調(diào)用join()的線程執(zhí)行完畢后才能執(zhí)行其它線程,在一定意義上,它可以實(shí)現(xiàn)同步的功能。例16:class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public void run()for(int i=0; i<4; i++)System.out.println(" " + i);tryThread.sleep(3000);}catch(InterruptedException e)System.out.println("Interrupted");}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();tryt1.join();}catch(InterruptedException e)t1.start();}}運(yùn)行結(jié)果為:01230123#p#3. class Object下常用的線程函數(shù)wait()、notify()和notifyAll()這三個(gè)函數(shù)由java.lang.Object類提供,用于協(xié)調(diào)多個(gè)線程對(duì)共享數(shù)據(jù)的存取。3.1 wait()、notify()和notifyAll()1) wait()函數(shù)有兩種形式:第一種形式接受一個(gè)毫秒值,用于在指定時(shí)間長(zhǎng)度內(nèi)暫停線程,使線程進(jìn)入停滯狀態(tài)。第二種形式為不帶參數(shù),代表waite()在notify()或notifyAll()之前會(huì)持續(xù)停滯。2) 當(dāng)對(duì)一個(gè)對(duì)象執(zhí)行notify()時(shí),會(huì)從線程等待池中移走該任意一個(gè)線程,并把它放到鎖標(biāo)志等待池中;當(dāng)對(duì)一個(gè)對(duì)象執(zhí)行notifyAll()時(shí),會(huì)從線程等待池中移走所有該對(duì)象的所有線程,并把它們放到鎖標(biāo)志等待池中。3) 當(dāng)調(diào)用wait()后,線程會(huì)釋放掉它所占有的“鎖標(biāo)志”,從而使線程所在對(duì)象中的其它synchronized數(shù)據(jù)可被別的線程使用。例17:下面,我們將對(duì)例11中的例子進(jìn)行修改class TestThreadMethod extends Threadpublic static int shareVar = 0;public TestThreadMethod(String name)super(name);}public synchronized void run()if(shareVar==0)for(int i=0; i<10; i++)shareVar++;if(shareVar==5)trythis.wait(); //(4)}catch(InterruptedException e)}}}if(shareVar!=0)System.out.print(Thread.currentThread().getName());System.out.println(" shareVar = " + shareVar);this.notify(); //(5)}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");TestThreadMethod t2 = new TestThreadMethod("t2");t1.start(); //(1)//t1.start();?。?)t2.start(); //(3)}}運(yùn)行結(jié)果為:t2 shareVar = 5因?yàn)閠1和t2是兩個(gè)不同對(duì)象,所以線程t2調(diào)用代碼(5)不能喚起線程t1。如果去掉代碼(2)的注釋,并注釋掉代碼(3),結(jié)果為:t1 shareVar = 5t1 shareVar = 10這是因?yàn)?,?dāng)代碼(1)的線程執(zhí)行到代碼(4)時(shí),它進(jìn)入停滯狀態(tài),并釋放對(duì)象的鎖狀態(tài)。接著,代碼(2)的線程執(zhí)行run(),由于此時(shí)shareVar值為5,所以執(zhí)行打印語(yǔ)句并調(diào)用代碼(5)使代碼(1)的線程進(jìn)入可執(zhí)行狀態(tài),然后代碼(2)的線程結(jié)束。當(dāng)代碼(1)的線程重新執(zhí)行后,它接著執(zhí)行for()循環(huán)一直到shareVar=10,然后打印shareVar。#p#3.2 wait()、notify()和synchronizedwaite()和notify()因?yàn)闀?huì)對(duì)對(duì)象的“鎖標(biāo)志”進(jìn)行操作,所以它們必須在synchronized函數(shù)或synchronized block中進(jìn)行調(diào)用。如果在non-synchronized函數(shù)或non-synchronized block中進(jìn)行調(diào)用,雖然能編譯通過(guò),但在運(yùn)行時(shí)會(huì)發(fā)生IllegalMonitorStateException的異常。例18:class TestThreadMethod extends Threadpublic int shareVar = 0;public TestThreadMethod(String name)super(name);new Notifier(this);}public synchronized void run()if(shareVar==0)for(int i=0; i<5; i++)shareVar++;System.out.println("i = " + shareVar);trySystem.out.println("wait......");this.wait();}catch(InterruptedException e)}}}}class Notifier extends Threadprivate TestThreadMethod ttm;Notifier(TestThreadMethod t)ttm = t;start();}public void run()while(true)trysleep(2000);}catch(InterruptedException e)/*1 要同步的不是當(dāng)前對(duì)象的做法 */synchronized(ttm)System.out.println("notify......");ttm.notify();}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();}}運(yùn)行結(jié)果為:i = 1wait......notify......i = 2wait......notify......i = 3wait......notify......i = 4wait......notify......i = 5wait......notify......4. wait()、notify()、notifyAll()和suspend()、resume()、sleep()的討論4.1 這兩組函數(shù)的區(qū)別1) wait()使當(dāng)前線程進(jìn)入停滯狀態(tài)時(shí),還會(huì)釋放當(dāng)前線程所占有的“鎖標(biāo)志”,從而使線程對(duì)象中的synchronized資源可被對(duì)象中別的線程使用;而suspend()和sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài)時(shí)不會(huì)釋放當(dāng)前線程所占有的“鎖標(biāo)志”。2) 前一組函數(shù)必須在synchronized函數(shù)或synchronized block中調(diào)用,否則在運(yùn)行時(shí)會(huì)產(chǎn)生錯(cuò)誤;而后一組函數(shù)可以non-synchronized函數(shù)和synchronized block中調(diào)用。4.2 這兩組函數(shù)的取舍Java2已不建議使用后一組函數(shù)。因?yàn)樵谡{(diào)用suspend()時(shí)不會(huì)釋放當(dāng)前線程所取得的“鎖標(biāo)志”,這樣很容易造成“死鎖”。
文章TAG:java消息消息隊(duì)列隊(duì)列java消息隊(duì)列具體說(shuō)明下

最近更新

相關(guān)文章