私はプロデューサーがArrayListのバッファ内のすべての場所を埋める際たびにプログラムが実行を停止します問題に遭遇しました。しかし、理論的には。コンシューマプロセスがまだget()関数に入る可能性があり、notEmptyセマフォが現在10までのシグナル値を取得する原因となります。したがって、消費者プロセスが信号値をセマフォnotFullに戻した後も、プロデューサプロセスは引き続き機能します。(セマフォ使用)は、Java並行処理プログラムについての奇妙なバグ
しかし、それだけで停止し、私は問題を見つけることができません。ここで
はプログラムです:
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Semaphore;
/**
* A bounded buffer maintains a fixed number of "slots". Items can be
* inserted into and removed from the buffer. The buffer has a maximum
* size.
*/
class BoundedBuffer2
{
// the maximum size of the bounded buffer
final public static int MAXSIZE = 10;
Semaphore notEmpty = new Semaphore(0);
Semaphore notFull = new Semaphore(MAXSIZE);
Semaphore sema = new Semaphore(1);
// the buffer
volatile List<Integer> buffer;
public BoundedBuffer2()
{
buffer = new ArrayList<Integer>();
}
// add an element to the end of the buffer if it is not full
public synchronized void put(int input)
throws InterruptedException
{
notFull.acquire();
sema.acquire();
buffer.add(input);
sema.release();
notEmpty.release();
}
// take an element from the front of the buffer
public synchronized int get()
throws InterruptedException
{
notEmpty.acquire();
sema.acquire();
int result = buffer.remove(0);
sema.release();
notFull.release();
return result;
}
public int size()
{
int result = buffer.size();
return result;
}
}
/**
* An instance of the Producer class produces new integers at random
* intervals, and inserts them into a bounded buffer.
*/
class Producer2 extends Thread
{
// the buffer in which to insert new integers
BoundedBuffer2 buffer;
public Producer2(BoundedBuffer2 buffer)
{
this.buffer = buffer;
}
public void run()
{
Random random = new Random();
try {
while (true) {
Thread.sleep(100);
//insert a random integer
int next = random.nextInt();
buffer.put(next);
System.err.println("b.size() increases to " + buffer.size());
}
}
catch (InterruptedException e) {}
}
}
/**
* An instance of the Consumer class consumes integers from a bounded
* buffer at random intervals.
*/
class Consumer2 extends Thread
{
// the buffer in which to insert new integers
BoundedBuffer2 buffer;
public Consumer2(BoundedBuffer2 buffer)
{
this.buffer = buffer;
}
public void run()
{
Random random = new Random();
try {
while (true) {
Thread.sleep(200);
//get the next integer from the buffer
int next = buffer.get();
System.err.println("next = " + next);
System.err.println("b.size() reducted to " + buffer.size());
}
}
catch (InterruptedException e) {}
}
}
public class UseBuffer2
{
public static void main(String [] args)
{
BoundedBuffer2 buffer = new BoundedBuffer2();
Producer2 p = new Producer2(buffer);
Consumer2 c = new Consumer2(buffer);
p.start();
c.start();
}
}
ここでは、コンソールに出力されます。
b.size() increases to 1
b.size() increases to 2
next = 400524264
b.size() reducted to 1
b.size() increases to 2
b.size() increases to 3
next = 241523118
b.size() reducted to 2
b.size() increases to 3
next = -1618289090
b.size() reducted to 2
b.size() increases to 3
b.size() increases to 4
next = -316455080
b.size() reducted to 3
b.size() increases to 4
b.size() increases to 5
next = 338682909
b.size() reducted to 4
b.size() increases to 5
b.size() increases to 6
next = -961276708
b.size() reducted to 5
b.size() increases to 6
b.size() increases to 7
next = 2056804692
b.size() reducted to 6
b.size() increases to 7
b.size() increases to 8
next = -301063524
b.size() reducted to 7
b.size() increases to 8
b.size() increases to 9
next = -148582342
b.size() reducted to 8
b.size() increases to 9
b.size() increases to 10
next = -2076430410
b.size() reducted to 9
b.size() increases to 10
ありませんか? – HendraWD
セマフォーのいずれかに許可を与えていないため、許可を得ることができず、無期限にブロックすることができません。 –
tl; dr javaが[Conditions](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Condition.html)の場合、セマフォを使用する理由は何ですか? – Fildor