저는 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이 말한 것과 동일합니다. 스레드는 자체 잠금 인스턴스를가집니다. 나는 자물쇠와 상태를 정적으로 만들었고 효과가 있었다. –