Producer/Consumer Java 中使用锁的线程示例
Producer/Consumer thread example in Java using lock
public class ConsumerThreadExample {
public static void main(String[] args) throws InterruptedException {
Consumer c = new Consumer();
Thread a = new Thread(()->{while(true)c.consume();});
Thread b = new Thread(()->{while(true)c.supply();});
a.start();
b.start();
a.join();
b.join();
System.out.println("finish");
}
}
class Consumer{
private List<Integer> buffer = new ArrayList<>();
private Lock lock = new ReentrantLock();
private Condition notEnough = lock.newCondition();
private Condition toomuch = lock.newCondition();
public void consume(){
lock.lock();
try{
while(buffer.isEmpty()){notEnough.await();
System.out.println("consume waiting");}
System.out.println(buffer);
for(int i = 0; i < buffer.size(); i++){
System.out.println("consume "+ buffer.remove(i));
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("signal supply");
toomuch.signal();
}
catch (Exception e){}
finally {
lock.unlock();
}
}
public void supply(){
lock.lock();
try{
while(!buffer.isEmpty()){toomuch.await();
System.out.println("supply waiting");}
System.out.println("Adding");
buffer.add(1);
buffer.add(3);
buffer.add(5);
System.out.println(buffer);
System.out.println("signal consume");
notEnough.signal();
}
catch (Exception e){}
finally {
lock.unlock();
}
}
}
大家好,考虑上面的代码,我想练习经典线程示例 consumer/producer。所以我希望代码用 supply() 填充缓冲区,
然后向 consume() 发出信号以消耗 buffer.Whenever 缓冲区为空,consume() 再次向 supply() 发出信号,因此 on.But 输出看起来有点奇怪。输出:
Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]
为什么它消耗 1 和 5 然后发出信号 supply()?
3在哪里?为什么不是1,3,5的顺序?
好在第一次迭代
i = 0
buffer = [1, 3, 5]
然后你删除了 1。在第二次迭代中
i = 1
buffer = [3, 5]
然后删除 5。然后退出循环,因为 i 现在大于长度。
public class ConsumerThreadExample {
public static void main(String[] args) throws InterruptedException {
Consumer c = new Consumer();
Thread a = new Thread(()->{while(true)c.consume();});
Thread b = new Thread(()->{while(true)c.supply();});
a.start();
b.start();
a.join();
b.join();
System.out.println("finish");
}
}
class Consumer{
private List<Integer> buffer = new ArrayList<>();
private Lock lock = new ReentrantLock();
private Condition notEnough = lock.newCondition();
private Condition toomuch = lock.newCondition();
public void consume(){
lock.lock();
try{
while(buffer.isEmpty()){notEnough.await();
System.out.println("consume waiting");}
System.out.println(buffer);
for(int i = 0; i < buffer.size(); i++){
System.out.println("consume "+ buffer.remove(i));
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("signal supply");
toomuch.signal();
}
catch (Exception e){}
finally {
lock.unlock();
}
}
public void supply(){
lock.lock();
try{
while(!buffer.isEmpty()){toomuch.await();
System.out.println("supply waiting");}
System.out.println("Adding");
buffer.add(1);
buffer.add(3);
buffer.add(5);
System.out.println(buffer);
System.out.println("signal consume");
notEnough.signal();
}
catch (Exception e){}
finally {
lock.unlock();
}
}
}
大家好,考虑上面的代码,我想练习经典线程示例 consumer/producer。所以我希望代码用 supply() 填充缓冲区, 然后向 consume() 发出信号以消耗 buffer.Whenever 缓冲区为空,consume() 再次向 supply() 发出信号,因此 on.But 输出看起来有点奇怪。输出:
Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]
signal consume
consume waiting
[1, 3, 5]
consume 1
consume 5
signal supply
[3]
consume 3
signal supply
supply waiting
Adding
[1, 3, 5]
为什么它消耗 1 和 5 然后发出信号 supply()? 3在哪里?为什么不是1,3,5的顺序?
好在第一次迭代
i = 0
buffer = [1, 3, 5]
然后你删除了 1。在第二次迭代中
i = 1
buffer = [3, 5]
然后删除 5。然后退出循环,因为 i 现在大于长度。