私はJavaの初心者です。私はJavaの同時実行性を学びたいと考えています。私は生産者 - 消費者問題(単一の生産者と消費者)のための簡単なコードを書いています。データが利用可能なときに消費者に通知されないため、デッドロックが発生しているようです。コードを見直してもらえますか?あなたが実行されているためロックや条件を使用してこのプロデューサ - コンシューマのJavaでデッドロックが発生するのはなぜですか?
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.locks.*;
class ThreadFactory implements Runnable{
List<String> list = new ArrayList<>();
Thread prThread;
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final int CAPACITY = 10;
public enum Role{
PRODUCER,
CONSUMER
};
Role role;
public int i = 0;
private void produce() throws InterruptedException {
while(true){
lock.lock();
try{
while(list.size() == CAPACITY){
System.out.println("List is full to its CAPACITY, waiting");
notEmpty.await();
}
String str = "Data " + i++;
System.out.println("Putting " + str + " to list");
list.add(str);
notFull.signalAll();
}
finally{
lock.unlock();
Thread.sleep(500);
}
}
}
private void consume() throws InterruptedException{
while(true){
lock.lock();
try{
while(list.size() == 0){
System.out.println("List is empty, waiting");
notFull.await();
}
String str = list.remove(list.size()-1);
System.out.println("Popping " + str + " from list");
notEmpty.signal();
}
finally{
lock.unlock();
}
}
}
public void run(){
System.out.println("Starting thread " + prThread.getName());
try{
if(role == Role.PRODUCER){
produce();
}
else if(role == Role.CONSUMER){
consume();
}
}
catch(InterruptedException e){
System.out.println("Thread interrupted");
}
}
public ThreadFactory(List<String> l, int role, String name){
this.list = l;
prThread = new Thread(this, name);
if(role == 0)
this.role = Role.PRODUCER;
else
this.role = Role.CONSUMER;
prThread.start();
}
}
public class ProducerConsumer{
public static void main(String[] args){
List<String> l = new ArrayList<>();
ThreadFactory c = new ThreadFactory(l,1, "Consumer");
ThreadFactory p = new ThreadFactory(l,0, "Producer");
}
}
コンシューマまたはプロデューサのいずれかがロックを取得してその状態が発生するのを待つときに、ロックが解除されないようです。そのため、コードnotEmpty.await()を囲みます。 notFull.await(); lock.unlock()とlock.lock()によって呼び出されます。 – Shinchan
提案に感謝します。この問題は@Nathanの言葉と同じでした。スレッドには独自のロックインスタンスがありました。私はロックと条件を静的にし、それは働いた。 –