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

首頁 > 產(chǎn)品 > 問答 > java消息隊列,java消息隊列應用在哪些場景 具體說明下

java消息隊列,java消息隊列應用在哪些場景 具體說明下

來源:整理 時間:2025-03-26 01:46:18 編輯:智能門戶 手機版

本文目錄一覽

1,java消息隊列應用在哪些場景 具體說明下

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

java消息隊列應用在哪些場景 具體說明下

2,分布式消息隊列 java 哪個好

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

分布式消息隊列 java 哪個好

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

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

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

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

ActiveMQ,是Apache出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實現(xiàn),盡管JMS規(guī)范出臺已經(jīng)是很久的事情了,但是JMS在當今的J2EE應用中間仍然扮演著特殊的地位?! etaQ,是一款完全的隊列模型消息中間件,服務器使用Java語言編寫,可在多種軟硬件平臺上部署??蛻舳酥С諮ava、C++編程語言。單臺服務器可支持1萬以上個消息隊列,通過擴容服務器,隊列數(shù)幾乎可任意橫向擴展。每個隊列都是持久化、長度無限(取決于磁盤空間大?。?、并且可從隊列任意位置開始消費
現(xiàn)在出來個kafka你可以研究下,這個是異步的,效率賊高!
ActiveMQ,是Apache出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實現(xiàn),盡管JMS規(guī)范出臺已經(jīng)是很久的事情了,但是JMS在當今的J2EE應用中間仍然扮演著特殊的地位。MetaQ,是一款完全的隊列模型消息中間件,服務器使用Java語言編寫,可在多種軟硬件平臺上部署。客戶端支持Java、C++編程語言。單臺服務器可支持1萬以上個消息隊列,通過擴容服務器,隊列數(shù)幾乎可任意橫向擴展。每個隊列都是持久化、長度無限(取決于磁盤空間大?。?、并且可從隊列任意位置開始消費
開源JMS供應商 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的項目,應用應該要多一些

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

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

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

java中的消息隊列消息隊列是線程間通訊的手段: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;}}因為java中是locked by object的所以添加synchronized 就可以用于線程同步鎖定對象可以作為多線程處理多任務的存放task的隊列。他的client包括封裝好的task類以及thread類Java的多線程-線程間的通信2009-08-25 21:581. 線程的幾種狀態(tài)線程有四種狀態(tài),任何一個線程肯定處于這四種狀態(tài)中的一種:1) 產(chǎn)生(New):線程對象已經(jīng)產(chǎn)生,但尚未被啟動,所以無法執(zhí)行。如通過new產(chǎn)生了一個線程對象后沒對它調用start()函數(shù)之前。2) 可執(zhí)行(Runnable):每個支持多線程的系統(tǒng)都有一個排程器,排程器會從線程池中選擇一個線程并啟動它。當一個線程處于可執(zhí)行狀態(tài)時,表示它可能正處于線程池中等待排排程器啟動它;也可能它已正在執(zhí)行。如執(zhí)行了一個線程對象的start()方法后,線程就處于可執(zhí)行狀態(tài),但顯而易見的是此時線程不一定正在執(zhí)行中。3) 死亡(Dead):當一個線程正常結束,它便處于死亡狀態(tài)。如一個線程的run()函數(shù)執(zhí)行完畢后線程就進入死亡狀態(tài)。4) 停滯(Blocked):當一個線程處于停滯狀態(tài)時,系統(tǒng)排程器就會忽略它,不對它進行排程。當處于停滯狀態(tài)的線程重新回到可執(zhí)行狀態(tài)時,它有可能重新執(zhí)行。如通過對一個線程調用wait()函數(shù)后,線程就進入停滯狀態(tài),只有當兩次對該線程調用notify或notifyAll后它才能兩次回到可執(zhí)行狀態(tài)。2. class Thread下的常用函數(shù)函數(shù)2.1 suspend()、resume()1) 通過suspend()函數(shù),可使線程進入停滯狀態(tài)。通過suspend()使線程進入停滯狀態(tài)后,除非收到resume()消息,否則該線程不會變回可執(zhí)行狀態(tài)。2) 當調用suspend()函數(shù)后,線程不會釋放它的“鎖標志”。例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)}}運行結果為:t2 shareVar = 5i. 當代碼(5)的t1所產(chǎn)生的線程運行到代碼(1)處時,該線程進入停滯狀態(tài)。然后排程器從線程池中喚起代碼(4)的t2所產(chǎn)生的線程,此時shareVar值不為0,所以執(zhí)行else中的語句。ii. 也許你會問,那執(zhí)行代碼(2)后為什么不會使t1進入可執(zhí)行狀態(tài)呢?正如前面所說,t1和t2是兩個不同對象的線程,而代碼(1)和(2)都只對當前對象進行操作,所以t1所產(chǎn)生的線程執(zhí)行代碼(1)的結果是對象t1的當前線程進入停滯狀態(tài);而t2所產(chǎn)生的線程執(zhí)行代碼(2)的結果是把對象t2中的所有處于停滯狀態(tài)的線程調回到可執(zhí)行狀態(tài)。iii. 那現(xiàn)在把代碼(4)注釋掉,并去掉代碼(3)的注釋,是不是就能使t1重新回到可執(zhí)行狀態(tài)呢?運行結果是什么也不輸出。為什么會這樣呢?也許你會認為,當代碼(5)所產(chǎn)生的線程執(zhí)行到代碼(1)時,它進入停滯狀態(tài);而代碼(3)所產(chǎn)生的線程和代碼(5)所產(chǎn)生的線程是屬于同一個對象的,那么就當代碼(3)所產(chǎn)生的線程執(zhí)行到代碼(2)時,就可使代碼(5)所產(chǎn)生的線程執(zhí)行回到可執(zhí)行狀態(tài)。但是要清楚,suspend()函數(shù)只是讓當前線程進入停滯狀態(tài),但并不釋放當前線程所獲得的“鎖標志”。所以當代碼(5)所產(chǎn)生的線程進入停滯狀態(tài)時,代碼(3)所產(chǎn)生的線程仍不能啟動,因為當前對象的“鎖標志”仍被代碼(5)所產(chǎn)生的線程占有。#p#2.2 sleep()1) sleep ()函數(shù)有一個參數(shù),通過參數(shù)可使線程在指定的時間內(nèi)進入停滯狀態(tài),當指定的時間過后,線程則自動進入可執(zhí)行狀態(tài)。2) 當調用sleep ()函數(shù)后,線程不會釋放它的“鎖標志”。例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();?。?)}}運行結果為:t1 : 0t1 : 1t1 : 2t1 : 0t1 : 1t1 : 2由結果可證明,雖然在run()中執(zhí)行了sleep(),但是它不會釋放對象的“鎖標志”,所以除非代碼(1)的線程執(zhí)行完run()函數(shù)并釋放對象的“鎖標志”,否則代碼(2)的線程永遠不會執(zhí)行。如果把代碼(2)注釋掉,并去掉代碼(3)的注釋,結果將變?yōu)椋簍1 : 0t2 : 0t1 : 1t2 : 1t1 : 2t2 : 2由于t1和t2是兩個對象的線程,所以當線程t1通過sleep()進入停滯時,排程器會從線程池中調用其它的可執(zhí)行線程,從而t2線程被啟動。例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();}}運行結果為:t1 : 0t2 : 0t2 : 1t1 : 1t2 : 2t2 : 3t1 : 2t2 : 4t1 : 3t1 : 4由于線程t1調用了sleep(200),而線程t2調用了sleep(100),所以線程t2處于停滯狀態(tài)的時間是線程t1的一半,從從結果反映出來的就是線程t2打印兩倍次線程t1才打印一次。#p#2.3 yield()1) 通過yield ()函數(shù),可使線程進入可執(zhí)行狀態(tài),排程器從可執(zhí)行狀態(tài)的線程中重新進行排程。所以調用了yield()的函數(shù)也有可能馬上被執(zhí)行。2) 當調用yield ()函數(shù)后,線程不會釋放它的“鎖標志”。例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();?。?)}}運行結果為:t1 : 0t1 : 1t1 : 2t1 : 3t1 : 0t1 : 1t1 : 2t1 : 3從結果可知調用yield()時并不會釋放對象的“鎖標志”。如果把代碼(1)注釋掉,并去掉代碼(2)的注釋,結果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3從結果可知,雖然t1線程調用了yield(),但它馬上又被執(zhí)行了。2.4 sleep()和yield()的區(qū)別1) sleep()使當前線程進入停滯狀態(tài),所以執(zhí)行sleep()的線程在指定的時間內(nèi)肯定不會執(zhí)行;yield()只是使當前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。2) sleep()可使優(yōu)先級低的線程得到執(zhí)行的機會,當然也可以讓同優(yōu)先級和高優(yōu)先級的線程有執(zhí)行的機會;yield()只能使同優(yōu)先級的線程有執(zhí)行的機會。例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();}}運行結果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3由結果可見,通過sleep()可使優(yōu)先級較低的線程有執(zhí)行的機會。注釋掉代碼(2),并去掉代碼(1)的注釋,結果為:t1 : 0t1 : 1t1 : 2t1 : 3t2 : 0t2 : 1t2 : 2t2 : 3可見,調用yield(),不同優(yōu)先級的線程永遠不會得到執(zhí)行機會。2.5 join()使調用join()的線程執(zhí)行完畢后才能執(zhí)行其它線程,在一定意義上,它可以實現(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();}}運行結果為:01230123#p#3. class Object下常用的線程函數(shù)wait()、notify()和notifyAll()這三個函數(shù)由java.lang.Object類提供,用于協(xié)調多個線程對共享數(shù)據(jù)的存取。3.1 wait()、notify()和notifyAll()1) wait()函數(shù)有兩種形式:第一種形式接受一個毫秒值,用于在指定時間長度內(nèi)暫停線程,使線程進入停滯狀態(tài)。第二種形式為不帶參數(shù),代表waite()在notify()或notifyAll()之前會持續(xù)停滯。2) 當對一個對象執(zhí)行notify()時,會從線程等待池中移走該任意一個線程,并把它放到鎖標志等待池中;當對一個對象執(zhí)行notifyAll()時,會從線程等待池中移走所有該對象的所有線程,并把它們放到鎖標志等待池中。3) 當調用wait()后,線程會釋放掉它所占有的“鎖標志”,從而使線程所在對象中的其它synchronized數(shù)據(jù)可被別的線程使用。例17:下面,我們將對例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<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)}}運行結果為:t2 shareVar = 5因為t1和t2是兩個不同對象,所以線程t2調用代碼(5)不能喚起線程t1。如果去掉代碼(2)的注釋,并注釋掉代碼(3),結果為:t1 shareVar = 5t1 shareVar = 10這是因為,當代碼(1)的線程執(zhí)行到代碼(4)時,它進入停滯狀態(tài),并釋放對象的鎖狀態(tài)。接著,代碼(2)的線程執(zhí)行run(),由于此時shareVar值為5,所以執(zhí)行打印語句并調用代碼(5)使代碼(1)的線程進入可執(zhí)行狀態(tài),然后代碼(2)的線程結束。當代碼(1)的線程重新執(zhí)行后,它接著執(zhí)行for()循環(huán)一直到shareVar=10,然后打印shareVar。#p#3.2 wait()、notify()和synchronizedwaite()和notify()因為會對對象的“鎖標志”進行操作,所以它們必須在synchronized函數(shù)或synchronized block中進行調用。如果在non-synchronized函數(shù)或non-synchronized block中進行調用,雖然能編譯通過,但在運行時會發(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 要同步的不是當前對象的做法 */synchronized(ttm)System.out.println("notify......");ttm.notify();}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();}}運行結果為: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()使當前線程進入停滯狀態(tài)時,還會釋放當前線程所占有的“鎖標志”,從而使線程對象中的synchronized資源可被對象中別的線程使用;而suspend()和sleep()使當前線程進入停滯狀態(tài)時不會釋放當前線程所占有的“鎖標志”。2) 前一組函數(shù)必須在synchronized函數(shù)或synchronized block中調用,否則在運行時會產(chǎn)生錯誤;而后一組函數(shù)可以non-synchronized函數(shù)和synchronized block中調用。4.2 這兩組函數(shù)的取舍Java2已不建議使用后一組函數(shù)。因為在調用suspend()時不會釋放當前線程所取得的“鎖標志”,這樣很容易造成“死鎖”。
java中的消息隊列消息隊列是線程間通訊的手段: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;}}因為java中是locked by object的所以添加synchronized 就可以用于線程同步鎖定對象可以作為多線程處理多任務的存放task的隊列。他的client包括封裝好的task類以及thread類Java的多線程-線程間的通信2009-08-25 21:581. 線程的幾種狀態(tài)線程有四種狀態(tài),任何一個線程肯定處于這四種狀態(tài)中的一種:1) 產(chǎn)生(New):線程對象已經(jīng)產(chǎn)生,但尚未被啟動,所以無法執(zhí)行。如通過new產(chǎn)生了一個線程對象后沒對它調用start()函數(shù)之前。2) 可執(zhí)行(Runnable):每個支持多線程的系統(tǒng)都有一個排程器,排程器會從線程池中選擇一個線程并啟動它。當一個線程處于可執(zhí)行狀態(tài)時,表示它可能正處于線程池中等待排排程器啟動它;也可能它已正在執(zhí)行。如執(zhí)行了一個線程對象的start()方法后,線程就處于可執(zhí)行狀態(tài),但顯而易見的是此時線程不一定正在執(zhí)行中。3) 死亡(Dead):當一個線程正常結束,它便處于死亡狀態(tài)。如一個線程的run()函數(shù)執(zhí)行完畢后線程就進入死亡狀態(tài)。4) 停滯(Blocked):當一個線程處于停滯狀態(tài)時,系統(tǒng)排程器就會忽略它,不對它進行排程。當處于停滯狀態(tài)的線程重新回到可執(zhí)行狀態(tài)時,它有可能重新執(zhí)行。如通過對一個線程調用wait()函數(shù)后,線程就進入停滯狀態(tài),只有當兩次對該線程調用notify或notifyAll后它才能兩次回到可執(zhí)行狀態(tài)。2. class Thread下的常用函數(shù)函數(shù)2.1 suspend()、resume()1) 通過suspend()函數(shù),可使線程進入停滯狀態(tài)。通過suspend()使線程進入停滯狀態(tài)后,除非收到resume()消息,否則該線程不會變回可執(zhí)行狀態(tài)。2) 當調用suspend()函數(shù)后,線程不會釋放它的“鎖標志”。例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)}}運行結果為:t2 shareVar = 5i. 當代碼(5)的t1所產(chǎn)生的線程運行到代碼(1)處時,該線程進入停滯狀態(tài)。然后排程器從線程池中喚起代碼(4)的t2所產(chǎn)生的線程,此時shareVar值不為0,所以執(zhí)行else中的語句。ii. 也許你會問,那執(zhí)行代碼(2)后為什么不會使t1進入可執(zhí)行狀態(tài)呢?正如前面所說,t1和t2是兩個不同對象的線程,而代碼(1)和(2)都只對當前對象進行操作,所以t1所產(chǎn)生的線程執(zhí)行代碼(1)的結果是對象t1的當前線程進入停滯狀態(tài);而t2所產(chǎn)生的線程執(zhí)行代碼(2)的結果是把對象t2中的所有處于停滯狀態(tài)的線程調回到可執(zhí)行狀態(tài)。iii. 那現(xiàn)在把代碼(4)注釋掉,并去掉代碼(3)的注釋,是不是就能使t1重新回到可執(zhí)行狀態(tài)呢?運行結果是什么也不輸出。為什么會這樣呢?也許你會認為,當代碼(5)所產(chǎn)生的線程執(zhí)行到代碼(1)時,它進入停滯狀態(tài);而代碼(3)所產(chǎn)生的線程和代碼(5)所產(chǎn)生的線程是屬于同一個對象的,那么就當代碼(3)所產(chǎn)生的線程執(zhí)行到代碼(2)時,就可使代碼(5)所產(chǎn)生的線程執(zhí)行回到可執(zhí)行狀態(tài)。但是要清楚,suspend()函數(shù)只是讓當前線程進入停滯狀態(tài),但并不釋放當前線程所獲得的“鎖標志”。所以當代碼(5)所產(chǎn)生的線程進入停滯狀態(tài)時,代碼(3)所產(chǎn)生的線程仍不能啟動,因為當前對象的“鎖標志”仍被代碼(5)所產(chǎn)生的線程占有。#p#2.2 sleep()1) sleep ()函數(shù)有一個參數(shù),通過參數(shù)可使線程在指定的時間內(nèi)進入停滯狀態(tài),當指定的時間過后,線程則自動進入可執(zhí)行狀態(tài)。2) 當調用sleep ()函數(shù)后,線程不會釋放它的“鎖標志”。例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();?。?)}}運行結果為:t1 : 0t1 : 1t1 : 2t1 : 0t1 : 1t1 : 2由結果可證明,雖然在run()中執(zhí)行了sleep(),但是它不會釋放對象的“鎖標志”,所以除非代碼(1)的線程執(zhí)行完run()函數(shù)并釋放對象的“鎖標志”,否則代碼(2)的線程永遠不會執(zhí)行。如果把代碼(2)注釋掉,并去掉代碼(3)的注釋,結果將變?yōu)椋簍1 : 0t2 : 0t1 : 1t2 : 1t1 : 2t2 : 2由于t1和t2是兩個對象的線程,所以當線程t1通過sleep()進入停滯時,排程器會從線程池中調用其它的可執(zhí)行線程,從而t2線程被啟動。例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();}}運行結果為:t1 : 0t2 : 0t2 : 1t1 : 1t2 : 2t2 : 3t1 : 2t2 : 4t1 : 3t1 : 4由于線程t1調用了sleep(200),而線程t2調用了sleep(100),所以線程t2處于停滯狀態(tài)的時間是線程t1的一半,從從結果反映出來的就是線程t2打印兩倍次線程t1才打印一次。#p#2.3 yield()1) 通過yield ()函數(shù),可使線程進入可執(zhí)行狀態(tài),排程器從可執(zhí)行狀態(tài)的線程中重新進行排程。所以調用了yield()的函數(shù)也有可能馬上被執(zhí)行。2) 當調用yield ()函數(shù)后,線程不會釋放它的“鎖標志”。例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();?。?)}}運行結果為:t1 : 0t1 : 1t1 : 2t1 : 3t1 : 0t1 : 1t1 : 2t1 : 3從結果可知調用yield()時并不會釋放對象的“鎖標志”。如果把代碼(1)注釋掉,并去掉代碼(2)的注釋,結果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3從結果可知,雖然t1線程調用了yield(),但它馬上又被執(zhí)行了。2.4 sleep()和yield()的區(qū)別1) sleep()使當前線程進入停滯狀態(tài),所以執(zhí)行sleep()的線程在指定的時間內(nèi)肯定不會執(zhí)行;yield()只是使當前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行。2) sleep()可使優(yōu)先級低的線程得到執(zhí)行的機會,當然也可以讓同優(yōu)先級和高優(yōu)先級的線程有執(zhí)行的機會;yield()只能使同優(yōu)先級的線程有執(zhí)行的機會。例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();}}運行結果為:t1 : 0t1 : 1t2 : 0t1 : 2t2 : 1t1 : 3t2 : 2t2 : 3由結果可見,通過sleep()可使優(yōu)先級較低的線程有執(zhí)行的機會。注釋掉代碼(2),并去掉代碼(1)的注釋,結果為:t1 : 0t1 : 1t1 : 2t1 : 3t2 : 0t2 : 1t2 : 2t2 : 3可見,調用yield(),不同優(yōu)先級的線程永遠不會得到執(zhí)行機會。2.5 join()使調用join()的線程執(zhí)行完畢后才能執(zhí)行其它線程,在一定意義上,它可以實現(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();}}運行結果為:01230123#p#3. class Object下常用的線程函數(shù)wait()、notify()和notifyAll()這三個函數(shù)由java.lang.Object類提供,用于協(xié)調多個線程對共享數(shù)據(jù)的存取。3.1 wait()、notify()和notifyAll()1) wait()函數(shù)有兩種形式:第一種形式接受一個毫秒值,用于在指定時間長度內(nèi)暫停線程,使線程進入停滯狀態(tài)。第二種形式為不帶參數(shù),代表waite()在notify()或notifyAll()之前會持續(xù)停滯。2) 當對一個對象執(zhí)行notify()時,會從線程等待池中移走該任意一個線程,并把它放到鎖標志等待池中;當對一個對象執(zhí)行notifyAll()時,會從線程等待池中移走所有該對象的所有線程,并把它們放到鎖標志等待池中。3) 當調用wait()后,線程會釋放掉它所占有的“鎖標志”,從而使線程所在對象中的其它synchronized數(shù)據(jù)可被別的線程使用。例17:下面,我們將對例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<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)}}運行結果為:t2 shareVar = 5因為t1和t2是兩個不同對象,所以線程t2調用代碼(5)不能喚起線程t1。如果去掉代碼(2)的注釋,并注釋掉代碼(3),結果為:t1 shareVar = 5t1 shareVar = 10這是因為,當代碼(1)的線程執(zhí)行到代碼(4)時,它進入停滯狀態(tài),并釋放對象的鎖狀態(tài)。接著,代碼(2)的線程執(zhí)行run(),由于此時shareVar值為5,所以執(zhí)行打印語句并調用代碼(5)使代碼(1)的線程進入可執(zhí)行狀態(tài),然后代碼(2)的線程結束。當代碼(1)的線程重新執(zhí)行后,它接著執(zhí)行for()循環(huán)一直到shareVar=10,然后打印shareVar。#p#3.2 wait()、notify()和synchronizedwaite()和notify()因為會對對象的“鎖標志”進行操作,所以它們必須在synchronized函數(shù)或synchronized block中進行調用。如果在non-synchronized函數(shù)或non-synchronized block中進行調用,雖然能編譯通過,但在運行時會發(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 要同步的不是當前對象的做法 */synchronized(ttm)System.out.println("notify......");ttm.notify();}}}}public class TestThreadpublic static void main(String[] args)TestThreadMethod t1 = new TestThreadMethod("t1");t1.start();}}運行結果為: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()使當前線程進入停滯狀態(tài)時,還會釋放當前線程所占有的“鎖標志”,從而使線程對象中的synchronized資源可被對象中別的線程使用;而suspend()和sleep()使當前線程進入停滯狀態(tài)時不會釋放當前線程所占有的“鎖標志”。2) 前一組函數(shù)必須在synchronized函數(shù)或synchronized block中調用,否則在運行時會產(chǎn)生錯誤;而后一組函數(shù)可以non-synchronized函數(shù)和synchronized block中調用。4.2 這兩組函數(shù)的取舍Java2已不建議使用后一組函數(shù)。因為在調用suspend()時不會釋放當前線程所取得的“鎖標志”,這樣很容易造成“死鎖”。
文章TAG:java消息消息隊列隊列java消息隊列具體說明下

最近更新

  • 2112,是不是真的有2112呢2112,是不是真的有2112呢

    是不是真的有2112呢2,2112約等于多少3,2112是真的嗎4,2112是世界末日嗎5,2112年是世界大滅日嗎6,2112工程學校是什么意思1,是不是真的有2112呢2112是什么東西???信則有不信則無哎呀怕怕啊正確.....

    問答 日期:2025-03-26

  • 探險家人格探險家人格

    探險家和主角人格Match探險家人格和主角人格Match原因如下:1.互補性??傊?,探險家人格和主人公人格可以匹配,MBTI人格正在測試中,藝術家屬于探險家type人格type,探險家人格和主人公人格的.....

    問答 日期:2025-03-26

  • 大來自動化有限公司,世界十大工業(yè)自動化公司出爐!大來自動化有限公司,世界十大工業(yè)自動化公司出爐!

    江浙滬的自動化公司有:長園深瑞繼保自動化有限公司、深圳厲安德自動化設備有限公司、深圳星河自動化有限公司自動化公司介紹范文自動化公司是一家以自動化為產(chǎn)業(yè)的公司,包括電氣自動化.....

    問答 日期:2025-03-26

  • 蜂窩移動數(shù)據(jù)設置無法關閉,關閉蜂窩移動數(shù)據(jù)提示如何進行?蜂窩移動數(shù)據(jù)設置無法關閉,關閉蜂窩移動數(shù)據(jù)提示如何進行?

    蘋果手機蜂窩移動數(shù)據(jù)的關閉建議如何關閉蘋果手機的蜂窩數(shù)據(jù),即從數(shù)據(jù)傳輸?shù)浇粨Q都使用了分組技術。關閉蜂窩數(shù)據(jù),相當于關閉網(wǎng)絡,手機無法上網(wǎng),為什么很多軟件都無法關閉移動蜂窩數(shù)據(jù)?Ipho.....

    問答 日期:2025-03-25

  • 霸州非標自動化機械設備,那些行業(yè)涉及非標自動化設備?霸州非標自動化機械設備,那些行業(yè)涉及非標自動化設備?

    什么是非標準自動化設備?非標自動化是指根據(jù)客戶需求定制的非標自動化設備。哪些行業(yè)涉及非標自動化設備?如何維護非標自動化設備?廊坊傅瑩模具有限公司經(jīng)營范圍為:生產(chǎn)、銷售及研發(fā):模具.....

    問答 日期:2025-03-25

  • 奕珀自動化設備,中國十大自動化設備的公司奕珀自動化設備,中國十大自動化設備的公司

    合肥真人自動化科技有限公司經(jīng)營范圍為:測控技術、電子設備技術、工業(yè)自動化和自動化控制設備、機電/。合肥真人自動化科技有限公司怎么樣合肥真人自動化科技有限公司是一家注冊于2016.....

    問答 日期:2025-03-25

  • ios11蜂窩移動數(shù)據(jù),蘋果11怎么開蜂窩移動數(shù)據(jù)開關?ios11蜂窩移動數(shù)據(jù),蘋果11怎么開蜂窩移動數(shù)據(jù)開關?

    蘋果11不能用移動數(shù)據(jù)?蘋果11蜂窩數(shù)據(jù)不能再用了?iPhone11去掉蜂窩號怎么辦?iOS11控制中心如何打開蜂窩數(shù)據(jù)開關?蘋果11無法使用蜂窩移動數(shù)據(jù),可以嘗試以下方法。要打開蜂窩移動快捷開關,可.....

    問答 日期:2025-03-25

  • 自動化儀器儀表設備包括哪些東西,上海穎捷自動化儀器儀表設備有限公司自動化儀器儀表設備包括哪些東西,上海穎捷自動化儀器儀表設備有限公司

    自動化設備包含哪些問題?自動化設備,有哪些類型?什么-2儀表-3/主要用于礦山?具體有哪些設備???行業(yè)類型有哪些自動化儀表?問題2:-1設備主要包括什么-1設備范圍很廣,加工、組裝、測試等。的產(chǎn).....

    問答 日期:2025-03-25