H2O生产者java线程锁,重入锁

阿什·班克

我想通过三个线程连续生产 h2o 第一个线程将产生 h ,第二个将产生 h ,第三个将产生 o 。我怎么能用锁来做到这一点,消费者生产者

        package com.threads.reentrantlock.consumerproducer;

        import java.util.concurrent.locks.Condition;
        import java.util.concurrent.locks.Lock;
        import java.util.concurrent.locks.ReentrantLock;

        public class H2OProducer {
            static Lock lock = new ReentrantLock(true);
            static Condition condition = lock.newCondition();

            public static void main(String[] args) {
                try {
                    Thread h1 = new Thread(() -> {
                        try {
                            hydrogenProducer();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    });
                    Thread h2 = new Thread(() -> {
                        try {
                            hydrogenProducer();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    });
                    Thread o = new Thread(() -> {
                        try {
                            hydrogenProducer();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    });
                    h1.start();
                    h2.start();
                    o.start();

                    try {
                        h1.join();
                        h2.join();
                        o.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } catch (Exception e) {
                }

            }

            public static void hydrogenProducer() throws InterruptedException {
                try {
                    lock.lock();
                        System.out.println("h");
                condition.signalAll();
            } finally {
                lock.unlock();
            }

        }

        public static void oxygenProducer() throws InterruptedException {
            try {
                lock.lock();
                System.out.println("o");
                    condition.signalAll();
                } finally {
                    lock.unlock();
                }
            }
        }

我做错了什么

线程“Thread-2”中的异常 h java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) 处的 java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer. java:1261) 在 java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) 在 com.threads.reentrantlock.consumerproducer.H2OProducer.hydrogenProducer(H2OProducer.java:56) 在 com.threads.reentrantlock.consumerproducer .H2OProducer.lambda$2(H2OProducer.java:29) 在 java.lang.Thread.run(Thread.java:745)

莫卡洛姆侯赛因

您正在发出条件信号,但没有相应的等待。此外,还有一个错字 -hydrogenProducer()来自两个线程( Threado和 Thread h)的调用

我假设你想在生产H之前生产两个s O两个Hs 是由同一个线程生成还是由两个不同的线程生成并不重要我曾经randomSleep()演示过这种情况。

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class H2OProducer {
    static final int H2O_COUNT = 1_000;
    static final Random rand = new Random();

    static final Lock lock = new ReentrantLock(true);
    static final Condition oxzWait = lock.newCondition();
    static final Condition hydWait = lock.newCondition();

    static volatile int hydCount = 0;

    public static void main(String[] args) {
        try {
            Thread h1 = new Thread(() -> {
                try {
                    hydrogenProducer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            Thread h2 = new Thread(() -> {
                try {
                    hydrogenProducer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            Thread o = new Thread(() -> {
                try {
                    oxygenProducer();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            h1.setName("H1-Producer");
            h2.setName("H2-Producer");
            o.setName("Ox-Producer");

            h1.start();
            h2.start();
            o.start();

            try {
                h1.join();
                h2.join();
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
        }

    }

    public static void hydrogenProducer() throws InterruptedException {
        for (int i = 0; i < H2O_COUNT; i++) {
            lock.lock();
            try {
                while (hydCount == 2) {
                    hydWait.await();
                }

                hydCount++;
                System.out.println(Thread.currentThread().getName()+ ": H produced - " + i);

                if (hydCount == 2) {
                    oxzWait.signalAll();
                }
            } finally {
                lock.unlock();
            }

            randomSleep();
        }
    }

    public static void oxygenProducer() throws InterruptedException {
        for (int i = 0; i < H2O_COUNT; i++) {
            lock.lock();
            try {
                while (hydCount < 2) {
                    oxzWait.await();
                }

            hydCount = 0;
            System.out.println(Thread.currentThread().getName()+ ": O produced - " + i);
            System.out.println("");
            hydWait.signalAll();
            } finally {
                lock.unlock();
            }

            randomSleep();
        }
    } 

    public static void randomSleep() {
        int ms = rand.nextInt(500);
        try { 
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
        }
    }
}

但是,如果您希望每个H制作H人为每个H2O作品制作一个那么您可以查看CyclicBarrier如果需要保持顺序,也可以进行线程链接,例如,T1 -> T2 -> T3 -> T1 -> T2 -> T3 ->。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章