package com.duoduo.day330;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resource {
private String name;
private int count=1;
private boolean flag=false;
private Lock lock=new ReentrantLock(); //创建锁
private Condition con_pro=lock.newCondition(); //创建生产者
private Condition con_con=lock.newCondition(); //创建消费者
public void set(String name) throws InterruptedException{
lock.lock(); //上锁
try {
while(flag)
con_pro.await();
this.name=name+" "+count++;
System.out.println(Thread.currentThread().getName()+"producer"+this.name);
flag=true;
con_con.signal();
}
finally {
lock.unlock();
}
}
public void out() throws InterruptedException{
lock.lock();
try {
while(!flag)
con_con.await();
System.out.println(Thread.currentThread().getName()+" consumer"+this.name);
flag=false;
con_pro.signal();
}finally {
lock.unlock();
}
}
}
public class Producer implements Runnable{
private Resource res;
Producer(Resource res){
this.res=res;
}
public void run() {
while(true) {
try {
res.set("-----------商品----------");
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.duoduo.day330;
public class Consumer implements Runnable{
private Resource res;
Consumer(Resource res){
this.res=res;
}
public void run() {
while(true) {
try {
res.out();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试多线程类:
package com.duoduo.day330;
public class TestConPro {
public static void main(String [] args) {
Resource res=new Resource();
Producer pro=new Producer(res);
Consumer con=new Consumer(res);
Thread t1=new Thread(pro);
Thread t2=new Thread(con);
Thread t3=new Thread(pro);
Thread t4=new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
package com.duoduo.day330;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resource {
private String name;
private int count=1;
private boolean flag=false;
// private Lock lock=new ReentrantLock(); //创建锁
// private Condition con_pro=lock.newCondition(); //创建生产者
// private Condition con_con=lock.newCondition(); //创建消费者
public synchronized void set(String name) throws InterruptedException{
// lock.lock(); //上锁
try {
while(flag)
this.wait();
// con_pro.await();
this.name=name+" "+count++;
System.out.println(Thread.currentThread().getName()+"producer"+this.name);
flag=true;
this.notify();
// con_con.signal();
}
finally {
// lock.unlock();
}
}
public synchronized void out() throws InterruptedException{
// lock.lock();
try {
while(!flag)
this.wait();
// con_con.await();
System.out.println(Thread.currentThread().getName()+" consumer"+this.name);
flag=false;
// con_pro.signal();
}finally {
this.notify();
// lock.unlock();
}
}
}
其他类无需修改
结果测试:
分析原因:
在notify时只会唤醒本方线程 ,导致所有线程均等待 而需要唤醒对方线程 用notifyAll唤醒所有 ------
(三)原始不采用同步机制的版本
package com.duoduo.day330;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resource {
private String name;
private int count=1;
private boolean flag=false;
// private Lock lock=new ReentrantLock(); //创建锁
// private Condition con_pro=lock.newCondition(); //创建生产者
// private Condition con_con=lock.newCondition(); //创建消费者
public void set(String name) throws InterruptedException{
// lock.lock(); //上锁
try {
while(flag)
// this.wait();
// con_pro.await();
this.name=name+" "+count++;
System.out.println(Thread.currentThread().getName()+"producer"+this.name);
flag=true;
// this.notifyAll();
// con_con.signal();
}
finally {
// lock.unlock();
}
}
public void out() throws InterruptedException{
// lock.lock();
try {
while(!flag)
// this.wait();
// con_con.await();
System.out.println(Thread.currentThread().getName()+" consumer"+this.name);
flag=false;
// con_pro.signal();
}finally {
// this.notifyAll();
// lock.unlock();
}
}
}
根据结果看出:完全乱序 未生产就已经消费
由此可见“同步”的重要性~~
package com.duoduo.day041;
import java.util.concurrent.BlockingQueue;
//生产者
public class Producer implements Runnable{
private BlockingQueue queue;
public Producer(BlockingQueue queue) {
this.queue=queue;
}
public void run() {
System.out.println(Thread.currentThread().getName()+" is making product.");
String product="Made by"+Thread.currentThread().getName();
try {
queue.put(product); //将产品加入队列中
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
package com.duoduo.day041;
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{ //消费者
private BlockingQueue queue;
public Consumer(BlockingQueue queue) {
this.queue=queue;
}
public void run() {
try {
String product=queue.take(); //取product
System.out.println(Thread.currentThread().getName()+" is consuming product."+"("+product+")");
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
如果队列为空 take() 将阻塞,直到队列中有内容;如果队列为满 put() 将阻塞,指到队列有空闲位置。
它们响应中断,当收到中断请求的时候会抛出 InterruptedException,从而提前结束阻塞状态。
package com.duoduo.day041;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class BolckingTest {
public static void main(String [] args) {
BlockingQueue queue=new LinkedBlockingQueue(5);
//先生成两个product
for(int i=0;i<2;i++) {
new Thread(new Producer(queue),"producer-"+i).start();
}
//开启5个消费者 只能消费两个 另外3个就阻塞
for(int i=0;i<5;i++) {
new Thread(new Consumer(queue),"consumer-"+i).start();
}
//再生成3个product
for(int i=2;i<5;i++) {
new Thread(new Producer(queue),"producer-"+i).start();
}
}
}