使用ReentrantLock与wait()notifyAll对比实现线程通讯-生产者消费者模式
作者:互联网
实现目标:
1.ReentrantLock
建立一个容器,10个消费者,2个生产者,消费者消费数据,生产者生产数据。
容器中数据达到10,生产者等待,消费者进行消费
容器中数据为0,消费者等待,生产者进行生产
public class TestContainer<W> {
List<W> list=Collections.synchronizedList(new ArrayList());
final static int MAX=10;
static int count=0;
Lock lock = new ReentrantLock();
Condition producer = lock.newCondition();
Condition consumer = lock.newCondition();
//producer
public void put(W w){
try {
lock.lock();
while (list.size()==MAX){
producer.await();
}
list.add(w);
count++;
consumer.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
//consumer
public W get(){
W w=null;
try {
lock.lock();
while (list.size()==0){
consumer.await();
}
list.remove(0);
count--;
producer.signalAll();
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
return w;
}
public static void main(String[] args) {
TestContainer<String> c = new TestContainer();
//10个消费者
for (int i = 0; i <10 ; i++) {
new Thread(()->{
for (int j = 0; j <5 ; j++) {
System.out.println(Thread.currentThread().getName()+"---"+j);
c.get();
}
},"consumer"+i).start();
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
//2个生产者
for (int i = 0; i <2 ; i++) {
new Thread(()->{
for (int j = 0; j <30 ; j++) {
System.out.println(Thread.currentThread().getName()+"---"+j);
c.put("1111");
}
},"producer"+i).start();
}
}
}
2.wait()notifyAll实现上述目标
此代码存在问题,生产者wait(),让出锁,有可能生产者再次抢到锁,执行多余代码。
消费者也有此情况。
public class WaitNotifyAll {
final private LinkedList list = new LinkedList<>();
Object o=new Object();
final int MAX=10;
int count=0;
public void put(){
synchronized (this){
while(list.size()==MAX){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(o);
++count;
this.notifyAll();
}
}
public void get(){
synchronized (this){
while(list.size()==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.removeFirst();
count--;
this.notifyAll();
}
}
public static void main(String[] args) {
WaitNotifyAll c = new WaitNotifyAll();
//消费者
for (int i = 0; i <10 ; i++) {
new Thread(()->{
for (int j = 0; j <5 ; j++) {
System.out.println(Thread.currentThread().getName()+"----"+j);
c.get();
}
},"c").start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产者
for (int i = 0; i <2 ; i++) {
new Thread(()->{
for (int j = 0; j <30 ; j++) {
System.out.println(Thread.currentThread().getName()+"----"+j);
c.put();
}
},"p").start();
}
}
}
标签:Thread,int,notifyAll,ReentrantLock,list,线程,lock,new,public 来源: https://blog.csdn.net/weixin_39276203/article/details/114402002