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

本文探讨了Java中多线程同步的基本概念,通过生产者-消费者问题详细介绍了wait()和notify()方法以及LockSupport类中的park()和unpark()方法的使用方式,并对比了两者的差异。
摘要由CSDN通过智能技术生成

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+房源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值