Speaking of Blockingqueue, we are most familiar with the application of producer-consumer mode. However, if the upper-level code that calls the queue adds a synchronous block, the thread is deadlocked.
For example:
Staticblockingqueue<string> queue =NewLinkedblockingqueue (); /*** Sync Lock*/ StaticObject lock =NewObject (); Static voidproducer () {synchronized(lock) {Queue.put ("1"); } } Static voidCosumer () {synchronized(lock) {//once blocked, the current thread is suspended, the lock lock will never be released, and the producer cannot add elements, and the take will always blockString msg =Queue.take (); } }
But how do you improve the use of the queue when the synchronization block must be used? See the following example:
PackageCom.hdwang;ImportCom.alibaba.fastjson.JSON;ImportJava.util.concurrent.BlockingQueue;ImportJava.util.concurrent.LinkedBlockingQueue;/*** Created by Hdwang on 2018/4/17.*/ Public classMultiqueuesyntest {StaticBlockingqueue<packet> queue1 =NewLinkedblockingqueue (); StaticBlockingqueue<packet> queue2 =NewLinkedblockingqueue (); Static intSeq = 1; /*** Sync Lock*/ StaticObject lock =NewObject (); Static voidcommit (String msg) {synchronized(lock) {Packet Packet=NewPacket (); Packet.setseq (Seq++); Packet.setmsg (msg); Try { //queue1.put (packet);//Blocking Add elements while(queue1.size () = = Integer.max_value) {//the team is full and waitinglock.wait (); } queue1.offer (packet); //non-blocking add elements can beSystem.out.println ("Commit msg:" +json.tojsonstring (packet)); Lock.notifyall (); //Notification waiting thread } Catch(interruptedexception e) {e.printstacktrace (); } } } Static voidSend () { while(true) { synchronized(lock) {Try { //Packet Packet = Queue1.take ();//Blocking fetching elements//queue2.put (packet); while(Queue1.isempty ()) {//the team is empty and waitingLock.wait ();//Wait, surrender the lock.} Packet Packet= Queue1.poll ();//non-blocking fetching elements can beSYSTEM.OUT.PRINTLN ("Send msg:" +json.tojsonstring (packet)); Lock.notifyall (); //Notification waiting thread while(queue2.size () = = Integer.max_value) {//the team is full and waitingLock.wait ();//Wait, surrender the lock.} queue2.offer (packet); System.out.println ("Msg->queue2:" +json.tojsonstring (packet)); Lock.notifyall (); //Notification waiting thread } Catch(interruptedexception e) {e.printstacktrace (); } } } } Public Static voidMain (string[] args) {//producer 1 NewThread (NewRunnable () {@Override Public voidrun () { while(true){//constantly generating messagesCommit ("Hello1"); Try{Thread.Sleep (3000); } Catch(interruptedexception e) {e.printstacktrace (); }}}). Start (); //producer 2 NewThread (NewRunnable () {@Override Public voidrun () { while(true){//constantly generating messagesCommit ("Hello2"); Try{Thread.Sleep (3000); } Catch(interruptedexception e) {e.printstacktrace (); }}}). Start (); //Consumer NewThread (NewRunnable () {@Override Public voidrun () {send (); }}). Start (); } Static classpacket{intseq; String msg; Public intGetseq () {returnseq; } Public voidSetseq (intseq) { This. Seq =seq; } PublicString getmsg () {returnmsg; } Public voidsetmsg (String msg) { This. msg =msg; } }}
Run results
Commit msg:{"MSG": "Hello1", "seq": 1}send msg:{"msg": "Hello1", "seq": 1}msg->queue2:{"msg": "Hello1", "seq": 1} Commit msg:{"MSG": "Hello2", "seq": 2}send msg:{"msg": "Hello2", "seq": 2}msg->queue2:{"msg": "Hello2", "seq": 2} Commit msg:{"MSG": "Hello1", "seq": 3}send msg:{"msg": "Hello1", "seq": 3}msg->queue2:{"msg": "Hello1", "seq": 3} Commit msg:{"MSG": "Hello2", "seq": 4}send msg:{"msg": "Hello2", "seq": 4}msg->queue2:{"msg": "Hello2", "seq": 4} Commit msg:{"MSG": "Hello1", "seq": 5}send msg:{"msg": "Hello1", "seq": 5}msg->queue2:{"msg": "Hello1", "seq": 5} Commit msg:{"MSG": "Hello2", "seq": 6}send msg:{"msg": "Hello2", "seq": 6}msg->queue2:{"msg": "Hello2", "seq": 6}
Using Blockingqueue in Java Synchronization Code (synchronized)