Producer-Consumer solution using wait(), notify(), park() and unpark()

1. Introduce

In java, mutil-threads are used everywhere, applications not only take advantages of mutil-threads improving efficiency, but also encounter some confusing problems especially when threads are not synchronized correctly. Fortunately, java provides some basic primitives for synchronizing.

Producer-Consumer problem is a classic synchronization problem, in that situation a consumer is usually consuming util condition is not satisfied, then a producer starts to produce to make condition satisfied again, the consumer keeps waiting while producing.

2. wait() and notify()

Let's use wait() and notify() to illustrate producer-consumer problem. wait() and notify() are methods of Object class. Once a object's wait() is called, the current thread immediately suspends and waits until either another thread invokes notify() or notifyAll() method. Note that the current thread must own this obejct's monitor. The following codes will explain it.

       Thread consumer = new Thread(){

            @Override
            public void run() {

                // own blocker's monitor
                synchronized (blocker){

                    while(true){

                        // wait for producer to produce product
                        blocker.wait();

                        // consume product until product is used out
                        while (product > 0){
                            product--;
                            System.out.println("consume one product ...");
                        }
                    }
                }
            }
        };

        Thread producer = new Thread(){

            @Override
            public void run() {

                while(true){

                    // own blocker's monitor
                    synchronized (blocker){

                        // produce product when product is used out
                        if (product < 1){
                            product++;
                            System.out.println("produce one product ...");
                        }

                        // notice consumer to consume product
                        blocker.notify();
                    }
                }
            }
        };

        consumer.start();
        producer.start();

Notice that in above codes, wait() is invoked within a loop[ while (product <= 0) ] that rechecks condition upon return, it is because that wait() may be waken up spuriously, a so-called spurious wakeup.

(For more information about spurious wakeup, see multithreading - Do spurious wakeups in Java actually happen? - Stack Overflow).

3. park() and unpark()

park() and unpark() are methods in LockSupport class, play a role similar to wait() and notify(), but a important difference is that park() and unpark() don't require any lock, an example of producer-consumer solution using park() and unpark() could be written as follows:

        Thread consumer = new Thread(){

            @Override
            public void run() {

                // block on blocker
                while(true){
                    // wait for producer to produce product
                    while (product.get() <= 0){
                        LockSupport.park();
                    }

                    // consume product until product is used out
                    while (product.get() > 0){
                        product.decrementAndGet();;
                        System.out.println("consume one product ...");
                    }
                }
            }
        };

        Thread producer = new Thread(){

            @Override
            public void run() {

                while(true){

                    // produce product when product is used out
                    if (product.get() < 1){
                        product.incrementAndGet();
                        System.out.println("produce one product ...");
                    }

                    // notice consumer to consume product
                    LockSupport.unpark(consumer);
                }
            }
        };

        consumer.start();
        producer.start();

Note: Like wait(), park() could also be waken up spuriously, should be wrapped in a loop.

4. Difference

Compared to park() and unpark(), wait() and notify() have more limitions, for example:

1. notify() are limited to be after wait(), otherwise it will occur dead-lock.

2. The current thread must own the obejct's monitor before calling notify() and wait()

3. notify() chooses one thread arbitrarily to wake up if there are many threads waitting on the same object, while unpark() specifies which thread to be awakened.

👉👉👉 自己搭建的租房网站:全网租房助手,m.kuairent.com,每天新增 500+房源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值