Nach http://en.wikipedia.org/wiki/Producer-consumer_problem Ich möchte P/C-Problem mit Semaphor simulieren. Ich bekomme einen Stillstand und ich weiß nicht, was das Problem ist.Hersteller/Verbraucher mit Semaphore; Deadlock
public static void main(String[] args) {
CustomBlockingQueue blockingQueue = new CustomBlockingQueue();
new Thread(new Producer(blockingQueue)).start();
new Thread(new Consumer(blockingQueue)).start();
}
}
@SuppressWarnings("serial")
class CustomBlockingQueue extends LinkedList<Object> {
private static final int MAX_SIZE = 10;
private Semaphore mutex = new Semaphore(1);
private Semaphore fillCount = new Semaphore(0);
private Semaphore emptyCount = new Semaphore(MAX_SIZE);
@Override
public boolean offer(Object e) {
try {
mutex.acquire();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
boolean result = super.offer(e);
System.out.println("offer " + size());
try {
fillCount.release();
emptyCount.acquire();
mutex.release();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return result;
}
@Override
public Object poll() {
try {
mutex.acquire();
} catch (InterruptedException e2) {
e2.printStackTrace();
}
Object result = super.poll();
System.out.println("poll " + size());
try {
emptyCount.release();
fillCount.acquire();
mutex.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}
class Producer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Producer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(2));
blockingQueue.offer(new Object());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
private CustomBlockingQueue blockingQueue;
private Random random = new Random();
public Consumer(CustomBlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
TimeUnit.SECONDS.sleep(random.nextInt(4));
blockingQueue.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Mit Semaphore
Semaphore lösen das Problem der verlorenen Weckrufe. In der folgenden Lösung verwenden wir zwei Semaphore, fillCount und emptyCount, um das Problem zu lösen. fillCount ist die Anzahl der Elemente, die im Puffer gelesen werden, und emptyCount ist die Anzahl der verfügbaren Speicherbereiche im Puffer, in die Elemente geschrieben werden können. fillCount wird inkrementiert und emptyCount dekrementiert, wenn ein neues Element in den Puffer gestellt wurde. Wenn der Produzent versucht, leer zu dekrementieren, während sein Wert Null ist, wird der Erzeuger in den Ruhezustand versetzt. Beim nächsten Mal, wenn ein Gegenstand verbraucht wird, wird emptyCount inkrementiert und der Erzeuger wacht auf. Der Verbraucher arbeitet analog.
sparen Sie sich Kopfschmerzen: Verwenden Sie Thread-Safe-Warteschlangen. – jldupont
Einverstanden - dies ist alles für Sie in den Bibliotheken implementiert - keine Notwendigkeit, es auf die harte Tour zu tun! – DNA
Ich möchte für mich dieses Problem mit absichtlich Semaphor – ASD