美文网首页
Lock Condition实现生产者消费者模式

Lock Condition实现生产者消费者模式

作者: 啊啊啊哼哼哼 | 来源:发表于2020-05-16 18:05 被阅读0次

    Lock与Synchronized相比的优势:

    • 相比于Synchronized, Lock更加灵活,可以关联不同的Condition;
    • Lock中的RenentrantLock是可重入锁;
    • 可以定义优先级或者公平锁;

    lock.lock()一定要配对 lock.unlock(),并且 lock.unlock()放在finally块中,使得任何情况下都会解锁;

    await() 源码详解

    • 与当前Condition对象相关联的锁被当前线程释放,处于休眠状态,直到
    • 另一个线程 signal 或者 signalAll 唤醒了当前线程;
    • 另一个线程中断了当前线程;
    • 虚假唤醒。
    /**
         * Causes the current thread to wait until it is signalled or
         * {@linkplain Thread#interrupt interrupted}.
         *
         * <p>The lock associated with this {@code Condition} is atomically
         * released and the current thread becomes disabled for thread scheduling
         * purposes and lies dormant until <em>one</em> of four things happens:
         * <ul>
         * <li>Some other thread invokes the {@link #signal} method for this
         * {@code Condition} and the current thread happens to be chosen as the
         * thread to be awakened; or
         * <li>Some other thread invokes the {@link #signalAll} method for this
         * {@code Condition}; or
         * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
         * current thread, and interruption of thread suspension is supported; or
         * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
         * </ul>
         *
         * <p>In all cases, before this method can return the current thread must
         * re-acquire the lock associated with this condition. When the
         * thread returns it is <em>guaranteed</em> to hold this lock.
         *
         * <p>If the current thread:
         * <ul>
         * <li>has its interrupted status set on entry to this method; or
         * <li>is {@linkplain Thread#interrupt interrupted} while waiting
         * and interruption of thread suspension is supported,
         * </ul>
         * then {@link InterruptedException} is thrown and the current thread's
         * interrupted status is cleared. It is not specified, in the first
         * case, whether or not the test for interruption occurs before the lock
         * is released.
         *
         * <p><b>Implementation Considerations</b>
         *
         * <p>The current thread is assumed to hold the lock associated with this
         * {@code Condition} when this method is called.
         * It is up to the implementation to determine if this is
         * the case and if not, how to respond. Typically, an exception will be
         * thrown (such as {@link IllegalMonitorStateException}) and the
         * implementation must document that fact.
         *
         * <p>An implementation can favor responding to an interrupt over normal
         * method return in response to a signal. In that case the implementation
         * must ensure that the signal is redirected to another waiting thread, if
         * there is one.
         *
         * @throws InterruptedException if the current thread is interrupted
         *         (and interruption of thread suspension is supported)
         */
    

    signal() 源码详解

    • 唤醒一个等待在这个Condition对象上的线程;
    • 当前线程必须持有与Condition对象相关的lock,否则抛出IllegalMonitorStateException异常。
     /**
         * Wakes up one waiting thread.
         *
         * <p>If any threads are waiting on this condition then one
         * is selected for waking up. That thread must then re-acquire the
         * lock before returning from {@code await}.
         *
         * <p><b>Implementation Considerations</b>
         *
         * <p>An implementation may (and typically does) require that the
         * current thread hold the lock associated with this {@code
         * Condition} when this method is called. Implementations must
         * document this precondition and any actions taken if the lock is
         * not held. Typically, an exception such as {@link
         * IllegalMonitorStateException} will be thrown.
         */
    
    package thread;
    
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.Random;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    //用lock,condition实现生产者消费者模式
    public class ProducerConsumer2 {
        static Lock lock = new ReentrantLock();
        static Condition queueEmpty = lock.newCondition();
        static Condition queueFull = lock.newCondition();
    
        public static void main(String[] args) throws InterruptedException {
            Queue<Integer> queue = new LinkedList<>();
            Producer p1 = new Producer(queue);
            Consumer c1 = new Consumer(queue);
            p1.start();
            c1.start();
            p1.join();
            c1.join();
    
        }
    
        static class Producer extends Thread {
            Queue<Integer> queue;
    
            public Producer(Queue<Integer> queue) {
                this.queue = queue;
            }
    
            @Override
            public void run() {
                lock.lock();
                try {
                    while (!queue.isEmpty()) {
                        queueEmpty.await();
                    }
                    int tmp = new Random().nextInt();
                    queue.offer(tmp);
                    queueFull.signalAll();
                    System.out.println("Producing " + tmp);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
    
    
        }
    
        static class Consumer extends Thread {
            Queue<Integer> queue;
    
            public Consumer(Queue<Integer> queue) {
                this.queue = queue;
            }
    
            @Override
            public void run() {
                lock.lock();
                try {
                    while (queue.isEmpty()) {
                        queueFull.await();
                    }
                    int tmp = queue.poll();
                    queueEmpty.signalAll();
                    System.out.println("Consuming " + tmp);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
    
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Lock Condition实现生产者消费者模式

          本文链接:https://www.haomeiwen.com/subject/cxyrohtx.html