マルチスレッドの仕組みを理解するために、キューとReentrantLockを使用してプロデューサとコンシューマの問題をシミュレートしています。私のプロデューサースレッドはキューにデータを追加していますが、コンシューマーは削除していません。私はそれを正しく実装しているかどうかはわかりません。私はこれがすでに尋ねられているが、彼らは助けていないと理解しています。ReentrantLockとキューを使用するコンシューマ
パッケージの同時実行性。
if(lock.tryLock())
しかしtryLock
は、それが呼び出し時に別のスレッドによって保持されていないされている場合にのみ、ロックを取得:あなたの消費者に
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class Producer implements Runnable{
Queue<Integer> list;
Condition con;
ReentrantLock lock;
int size;
Producer(Queue q1, Condition con, ReentrantLock l1,int size)
{
this.list=q1;
this.con=con;
this.lock=l1;
this.size=size;
}
public void run()
{
for(int i =0;i<20;i++)
{
if(lock.tryLock())
{
while(list.size()==size)
{
try
{
con.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
list.add(i);
System.out.println("Producer "+ Thread.currentThread() +"added "+i+" to the List");
con.signalAll();
lock.unlock();
}
}
}
}
class Consumer implements Runnable{
Queue<Integer> list;
Condition con;
ReentrantLock lock;
int size;
Consumer(Queue q1, Condition con, ReentrantLock l1,int size)
{
this.list=q1;
this.con=con;
this.lock=l1;
this.size=size;
}
public void run()
{
for(int innerLoop =0;innerLoop<20;innerLoop++){
if(lock.tryLock()){
while(list.size()<1){
try {
con.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int i = (int) list.remove();
System.out.println("Consumer "+ Thread.currentThread() +"removed "+i+" from the List");
con.signalAll();
lock.unlock();
}
}
}
}
class SharedResource {
Queue list ;
Condition con;
ReentrantLock lock;
int size;
SharedResource()
{
size =20;
this.list=new LinkedList<Integer>();
lock = new ReentrantLock();
this.con = lock.newCondition();
}
public Queue getList() {
return list;
}
public void setList(Queue list) {
this.list = list;
}
public Condition getCon() {
return con;
}
public void setCon(Condition con) {
this.con = con;
}
public ReentrantLock getLock() {
return lock;
}
public void setLock(ReentrantLock lock) {
this.lock = lock;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
public class MYPRODUCERCONSUMER {
public static void main(String[] args) {
SharedResource producerCObj = new SharedResource();
Producer producer= new Producer(producerCObj.getList(), producerCObj.getCon(), producerCObj.getLock(), producerCObj.getSize());
Thread producerThread= new Thread(producer);
producerThread.start();
Consumer consumer= new Consumer(producerCObj.getList(), producerCObj.getCon(), producerCObj.getLock(), producerCObj.getSize());
Thread consumerThread= new Thread(consumer);
consumerThread.start();
}
}
ここからロックを解除する必要はありません。 ArrayBlockingQueueはスレッドセーフであり、スレッドが何もしないときにスレッドをブロックします。あなたはロックと条件ですべてのものを削除することができます。 –
@Nathan Hughesロックや条件を扱う方法を理解したいので、ArrayBlockingQueueをLinkedListに変更しました。 – crazyStart