'작은 책 세마포어'에서 'Exclusive Queue'문제에 대한 해결책을 쓰려고합니다. 문제는 다음과 같이 표시됩니다.Java Concurrency : Exclusive Queue 문제
스레드는 볼룸 댄서를 대표하며 2 가지 종류의 댄서, 리더 및 추종자가 댄스 플로어에 들어가기 전에 대기열에서 대기한다고 가정합니다. 리더가 도착하면 기다리는 추종자가 있는지 확인합니다. 그렇다면 둘 다 진행할 수 있습니다. 그렇지 않으면 기다립니다. 마찬가지로 팔로워가 도착하면 리더를 확인하고 이에 따라 수익을 얻거나 기다립니다. 또한, 각 리더는 한 명의 팔로어와 동시에 댄스를 불러올 수 있으며 그 반대도 마찬가지입니다.
책에는 세마포어를 사용하는 해결책이 언급되어 있지만 자바에서 객체 잠금을 사용하여 해결하려고합니다.
ExclusiveQueuePrimitive.java :
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ExclusiveQueuePrimitive {
public static void main(String[] args) throws InterruptedException {
System.out
.println("-------------------------------Application START-------------------");
final int NUM_RUN = 1000;
// for (int j=0; j<NUM_RUN; j++) {
for (;;) {
Counters c = new Counters();
int NUM_THREADS = 5;
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < NUM_THREADS; i++) {
Thread tl = new Thread(new Leader(c, i + 1));
Thread tf = new Thread(new Follower(c, i + 1));
threads.add(tf);
threads.add(tl);
tf.start();
tl.start();
}
for (int i = 0; i < threads.size(); i++) {
Thread t = threads.get(i);
t.join();
}
}
// System.out.println("--------------------------------Application END-------------------");
}
}
class Counters {
public int leaders = 0;
public int followers = 0;
//public final Lock countMutex = new ReentrantLock();
public boolean printed = false;
public Lock printLock = new ReentrantLock();
public final Lock leaderQueue = new ReentrantLock();
public final Lock followerQueue = new ReentrantLock();
public void dance(String str) {
System.out.println("" + str);
}
public void printLine() {
System.out.println("");
}
}
class Leader implements Runnable {
final Counters c;
final int num;
public Leader(Counters counters, int num) {
this.c = counters;
this.num = num;
}
@Override
public void run() {
synchronized (c.leaderQueue) {
try {
if (c.followers > 0) {
c.followers--;
synchronized (c.followerQueue) {
c.followerQueue.notify();
}
} else {
c.leaders++;
c.leaderQueue.wait();
}
c.dance("Leader " + num + " called dance");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Follower implements Runnable {
final Counters c;
final int num;
public Follower(Counters counters, int num) {
this.c = counters;
this.num = num;
}
@Override
public void run() {
synchronized (c.followerQueue) {
try {
if (c.leaders > 0) {
synchronized (c.leaderQueue) {
c.leaders--;
c.leaderQueue.notify();
}
} else {
c.followers++;
c.followerQueue.wait();
}
c.dance("Follower " + num + " called dance");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
그러나, 잠시 동안 실행 한 후,이 끊 여기 내 솔루션입니다. 교착 상태가 어디인지 어떻게 해결할 수 있는지 말해 줄 수 있어요. 또한 리더와 추종자가 한 쌍이 된 후에도 새로운 라인을 인쇄하고 싶습니다. 어떻게해야합니까?
마치 동일한 개체에서 동기화하지 않는 것처럼 보이지만 문제가되지 않습니까? –