java - 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();
}
}
}
我做错了什么
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
。H
两个s 是由同一个线程还是由两个不同的线程产生的并不重要。我曾经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 ->。
推荐阅读
- mysql - 如果 ID 更改 MYSQL,如何更新字段
- python - 基于列值的百分比
- python - Python Youtube-dl 转换为 mp4
- python - Python:消除录制音频片段之间的间隙
- java - JNI - 为什么 rt.jar System.load 不工作但包装的方法工作?
- python - 如何在没有系统消息的python中制作.exe文件
- javascript - 如何将异步函数的返回值分配给变量
- apache-spark - 我可以按百分比为所有 YARN 容器分配内存吗
- javascript - Javascript过滤功能必须始终写在一行上?
- python - 从现有数据框的子集自动创建数据框