Reprinted please indicate the source: http://blog.csdn.net/sunyujia/
The questions raised by netizens on the Forum can only be consumed for each 3 production sites. It is not difficult to do this for the sake of convenience.
Modified on the basis of the original http://blog.csdn.net/sunyujia/archive/2008/05/02/2362015.aspx.
The only difficulty is that three production threads are not the same. The two threads consumed are not the same thread. That is to say, it cannot be a thread that produces three in a row, and one thread consumes two in a row. If it is a thread that produces continuously, the program will be boring.
- Import java. util. arraylist;
- Import java. util. List;
- Import java. util. Concurrent. executorservice;
- Import java. util. Concurrent. executors;
- /**
- * Interesting producer and consumer problems
- * Two shards are consumed for each generation of three shards.
- * @ Author: sunyujia
- * @ Blog: http://blog.csdn.net/sunyujia/
- * @ Mail: sunyujia @ sunyujia@yahoo.cn
- */
- Public class executorservicetest {
- Private Static int producecount = 0;
- Private Static int consumecount = 0;
- Private Static object producelock = new object ();
- Private Static object consumelock = new object ();
- Public static void main (string [] ARGs ){
- Final list tasks = new arraylist ();
- System. Out. println ("myblog: http://blog.csdn.net/" + "sunyujia /");
- Final executorservice exec = executors. newcachedthreadpool ();
- For (INT I = 0; I <10; I ++) {// 10 producers
- Exec.exe cute (New runnable (){
- Public void run (){
- While (! Thread. interrupted ()){
- Try {
- Synchronized (consumelock ){
- If (producecount> = 3)
- Consumelock. Wait ();
- }
- Synchronized (producelock ){
- If (producecount <3 ){
- Tasks. Add (new object (); // Production
- System. Out. println (thread. currentthread (). getname () + "remaining production tasks:" + tasks. Size ());
- Producecount ++;
- If (producecount> = 3 ){
- Consumecount = 2; // you are prompted to consume only two
- System. Out. println ("producer reminder inventory now"
- + Tasks. Size ());
- Producelock. policyall ();
- }
- Thread. Yield ();
- }
- }
- Thread. Sleep (600); // Let the program run slowly for observation
- } Catch (interruptedexception e ){
- E. printstacktrace ();
- }
- }
- }
- });
- }
- For (INT I = 0; I <20; I ++) {// 20 consumers
- Exec.exe cute (New runnable (){
- Public void run (){
- While (! Thread. interrupted ()){
- Try {
- Synchronized (producelock ){
- If (consumecount <= 0)
- Producelock. Wait ();
- }
- Synchronized (consumelock ){
- If (consumecount> 0 ){
- Tasks. Remove (0); // consume
- System. Out. println (thread. currentthread (). getname () + "remaining tasks :"
- + Tasks. Size ());
- Consumecount --;
- If (consumecount <= 0 ){
- Producecount = 0; // three more are required
- System. Out. println ("Consumer reminder inventory now"
- + Tasks. Size ());
- Consumelock. policyall ();
- }
- }
- }
- Thread. Sleep (600); // Let the program run slowly for observation
- } Catch (interruptedexception e ){
- E. printstacktrace ();
- }
- }
- }
- });
- }
- Exec. Shutdown ();
- }
- }
The execution result is as follows:
Pool-1-thread-1 production task remaining: 1
Pool-1-thread-2 production task remaining: 2
Pool-1-thread-4 production task remaining: 3
Producer friendly reminder current inventory 3
Pool-1-thread-11: 2
Pool-1-thread-12: 1
Consumer friendly reminder current inventory 1
Pool-1-thread-5 production task remaining: 2
Pool-1-thread-6 production task remaining: 3
Pool-1-thread-7 production task left: 4
Producer reminder inventory 4
Pool-1-thread-14: 3
Pool-1-thread-16 remaining tasks: 2
Consumer reminder inventory 2
Pool-1-thread-3 production task remaining: 3
Pool-1-thread-2 production task left: 4
Pool-1-thread-4 production task remaining: 5
Producer friendly reminder inventory 5