我使用Reentrant Lock和condition编写了一个Producer Consumer程序。它工作正常,但我不确定实现是否正确。而且它似乎不是最佳的。有人可以验证这是否是一个正确的实现,而且你能告诉我,如何优化它,如 - 在真正需要的地方锁定
public class TestRL {
static class Observed {
boolean filled = false;
public void setFilled(boolean filled) {
this.filled = filled;
}
public boolean getFilled() {
return filled;
}
}
static Observed observed = new Observed();
static class Consumer implements Runnable {
Observed observed;
ReentrantLock lock;
Condition condition;
Consumer(Observed observed, ReentrantLock lock, Condition condition) {
this.observed = observed;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 20; i++) {
if (observed.getFilled() == false) {
try {
System.out.println("consumer waiting");
condition.await();
System.out.println("consumed");
Thread.sleep(400 + 1000 * i % 2);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
observed.setFilled(false);
condition.signalAll();
}else{
observed.setFilled(false);
condition.signalAll();
}
}
} finally {
lock.unlock();
}
}
}
static class Producer implements Runnable {
Observed observed;
ReentrantLock lock;
Condition condition;
Producer(Observed observed, ReentrantLock lock, Condition condition) {
this.observed = observed;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 20; i++) {
if (observed.getFilled() == true) {
try {
System.out.println("producer waiting");
condition.await();
System.out.println("produced");
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
observed.setFilled(true);
condition.signalAll();
}else{
observed.setFilled(true);
condition.signalAll();
}
}
} finally {
lock.unlock();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Producer producer = new Producer(observed, lock, condition);
Consumer consumer = new Consumer(observed, lock, condition);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();
}
}
答案 0 :(得分:3)
以下是另一个使用ReentrantLock&amp; amp; amp;条件。以防万一有人想要。
package reentrant_prodcons;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Reentrant_ProdCons {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Queue<Integer> queue=new LinkedList<Integer>();
ReentrantLock lock=new ReentrantLock();
Condition con=lock.newCondition();
final int size = 5;
new Producer(lock, con, queue, size).start();
new Consumer(lock, con, queue).start();
}
}
class Producer extends Thread{
ReentrantLock lock;
Condition con;
Queue<Integer> queue;
int size;
public Producer(ReentrantLock lock, Condition con, Queue<Integer> queue, int size) {
this.lock = lock;
this.con = con;
this.queue = queue;
this.size=size;
}
public void run(){
for(int i=0;i<10;i++){
lock.lock();
while(queue.size()==size){
try {
con.await();
} catch (InterruptedException ex) {
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
}
}
queue.add(i);
System.out.println("Produced : "+i);
con.signal();
lock.unlock();
}
}
}
class Consumer extends Thread{
ReentrantLock lock;
Condition con;
Queue<Integer> queue;
public Consumer(ReentrantLock lock, Condition con, Queue<Integer> queue) {
this.lock = lock;
this.con = con;
this.queue = queue;
}
public void run(){
for(int i=0;i<10;i++){
lock.lock();
while(queue.size()<1){
try {
con.await();
} catch (InterruptedException ex) {
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Consumed : "+queue.remove());
con.signal();
lock.unlock();
}
}
}
答案 1 :(得分:2)
希望有帮助。您可以通过更改使用者/生产者的等待时间来轻松检查代码中的上溢/下溢情况。
@Module
interface BaseFontFragmentModule {
@ContributesAndroidInjector(modules = [])
fun inject(): BaseFontFragment
}
@Module
interface BaseFontActivityModule{
@ContributesAndroidInjector(modules = [
BaseFontFragmentModule::class
])
fun inject(): BaseFontActivity
}
答案 2 :(得分:0)
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author sakshi
*/
public class ReentrantLockDemo {
static List<Integer> list = new ArrayList<Integer>();
static ReentrantLock lock = new ReentrantLock();
static Condition ProdCons = lock.newCondition();
static class Producer extends Thread {
List<Integer> list;
Producer(List<Integer> list) {
this.list = list;
}
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
if (list.size() >=1) {
try {
ProdCons.await();
} catch (InterruptedException ex) {
Logger.getLogger(ReentrantLockDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
list.add(i);
System.out.println("produce="+i);
ProdCons.signalAll();
lock.unlock();
}
}
}
static class Consumer extends Thread {
List<Integer> list;
Consumer(List<Integer> list) {
this.list = list;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
while (list.isEmpty()) {
try {
ProdCons.await();
} catch (InterruptedException ex) {
Logger.getLogger(ReentrantLockDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("consume=" +list.remove(0));
ProdCons.signalAll();
lock.unlock();
}
}
}
public static void main(String[] args) {
Producer produce = new Producer(list);
Consumer consume = new Consumer(list);
produce.start();
consume.start();
}
}
output:
produce=0
consume=0
produce=1
consume=1
produce=2
consume=2
produce=3
consume=3
produce=4
consume=4
produce=5
consume=5
produce=6
consume=6
produce=7
consume=7
produce=8
consume=8
produce=9
consume=9
答案 3 :(得分:0)
docker commit 1e7 apache/nifi:latest2