翔哥,您好,我刚听完第八章 和第九章的第一节。尝试着,写了一下producer-and-consumer 代码。
有几个问题,网上找了一些资料。有几个点还不是特别理解,求指导。
先上代码
package com.imooc.thread;
import java.util.LinkedList;
import java.util.List;
/**
* Single producer and consumer model
* @author tan3
*
*/
public class ProducerAndConsumer {
private static final List<Integer> BUFFER = new LinkedList<>();
private static final Integer BUFFER_MAX_SIZE = 3;
private static Integer productNum = 0;
private static final Integer ITERATION = 10;
public static void main(String[] args) {
final Object lock = new Object();
Thread producerThread = new Thread(new Runnable() {
@Override
public void run() {
// if the buffer is full, release the lock
synchronized(lock) {
for(int idx =0; idx < ITERATION ;idx++) {
if(BUFFER.size() == BUFFER_MAX_SIZE) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// if the buffer is not full, produce one good and wake up the consumer
try {
System.out.println(Thread.currentThread().getName()
+ " produce product: "+ productNum);
Thread.sleep(1000);
BUFFER.add(productNum++);
lock.notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
},"Producer");
Thread consumerThread = new Thread(new Runnable() {
@Override
public void run() {
for(int idx =0; idx < ITERATION ;idx++) {
// if the buffer is empty, release the lock and wake up the producer
synchronized(lock) {
if(BUFFER.size() == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// if the buffer is not empty, produce one good and tell the consumer to produce one
try {
System.out.println(Thread.currentThread().getName()
+ " consume product: "+ BUFFER.remove(0));
Thread.sleep(1000);
lock.notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
},"Consumer");
producerThread.start();
consumerThread.start();
/*try {
producerThread.join();
consumerThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
}
}
几个疑惑的点。
我这里用的是if(BUFFER.size() == BUFFER_MAX_SIZE) if语句进行判断的。网上说应该是用while 语句。 【在多线程中要测试某个条件的变化,使用if 还是while】 , 我测试了一下,我的程序跑了几遍。好像没出什么问题。(但是好像网上搜到的更多的是使用wait方法)。想知道这个地方到底该怎么理解。
https://www.geeksforgeeks.org/producer-consumer-solution-using-threads-java/
第二问题是关于join方法的。这个答案,最后用了join方法来确保生产线程 finishes before 消费者线程。(我试了一下,好像没什么用。)似乎这里不涉及抢占资源的问题吖?)
如果扩展multiple consumer and multiple producer,是不是BUFFER改成violate。以及voilate 是不是不可以跟final 并用。这里是用final 还是voilate。 怎么保证线程安全。我觉得final 就是保证线程安全比较好的方式了。。
可能概念有点多。学得越多越糊涂了。希望和大家探讨。