方法一、传统版
用 synchronized wait() 和notify() 方法实现:
资源类:
public class Resource {
private int apple = 0;
public synchronized void increace() { //
while (apple !=0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
apple++;
System. out .println("生成苹果成功!" );
notify();
}
public synchronized void decreace() {
while (apple ==0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
apple--;
System. out.println( "消费苹果成功!" );
notify();
}
测试:
public static void main(String[] args) {
Box box=new Box();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=5;i++) {
try {
box.increace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"AA").start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=5;i++) {
try {
box.decreace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"BB").start();
}
传统到2.0版本:
2.0版本:Condition和Lock
class ShareData{//资源类
private int number=0;
private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition();
public void increment()throws Exception {
lock.lock();
try {
//1判断
while(number!=0) {
//等待,不能生产
condition.await();
}
//2干活
number++;
System.out.println(Thread.currentThread().getName()+" \t "+number);
//3通知唤醒
condition.signalAll();
}catch(Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void decrement()throws Exception {
lock.lock();
try {
//1判断
while(number==0) {
//等待,不能生产
condition.await();
}
//2干活
number--;
System.out.println(Thread.currentThread().getName()+" \t "+number);
//3通知唤醒
condition.signalAll();
}catch(Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
测试:
public static void main(String[] args)throws Exception {
ShareData shareData=new ShareData();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=5;i++) {
try {
shareData.increment();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"AA").start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=5;i++) {
try {
shareData.decrement();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"BB").start();
}
3.0版本: BlockingQueue阻塞队列实现
class MyResource{
private volatile boolean FLAG=true;//默认开启,进行生产消费
private AtomicInteger atomicInteger=new AtomicInteger();
BlockingQueue<String> blockingQueue=null;
public MyResource(BlockingQueue<String> blockingQueue) {//构造方法注入,不写死用哪个阻塞队列实现
this.blockingQueue=blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}
public void myProd()throws Exception {
String data=null;
boolean retValue;
while(FLAG) {
data=atomicInteger.incrementAndGet()+"";//加1操作
retValue=blockingQueue.offer(data, 2L,TimeUnit.SECONDS);
if(retValue) {
System.out.println(Thread.currentThread().getName()+"\t 插入队列"+data+"成功");
}else {
System.out.println(Thread.currentThread().getName()+"\t 插入队列"+data+"失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName()+"\t 大老板叫停,表示FLAG=false,生产动作结束");
}
public void myConsumer()throws Exception {
String result=null;
while(FLAG) {
result=blockingQueue.poll(2L,TimeUnit.SECONDS);
if(null==result||result.equalsIgnoreCase("")) {//将此String 与另一个 String 进行比较,不考虑大小写。如果两个字符串的长度相等,并且两个字符串中的相应字符都相等(忽略大小写),则认为这两个字符串是相等的
FLAG=false;
System.out.println(Thread.currentThread().getName()+"\t 超过2秒钟没有取到蛋糕,消费退出");
System.out.println();
System.out.println();
return;
}
System.out.println(Thread.currentThread().getName()+"\t 消费队列蛋糕"+result+"成功");
}
}
public void stop() {
// TODO Auto-generated method stub
this.FLAG=false;
}
}
public static void main(String[] args)throws Exception {
MyResource myResource=new MyResource(new ArrayBlockingQueue<String>(10));
new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+"\t 生产线程启动");
try {
myResource.myProd();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
},"Prod").start();
new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+"\t消费线程启动");
System.out.println();
System.out.println();
try {
myResource.myConsumer();
System.out.println();
System.out.println();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
},"Consumer").start();
try {TimeUnit.SECONDS.sleep(5);}catch(InterruptedException e){e.printStackTrace();}
System.out.println();
System.out.println();
System.out.println();
System.out.println("5秒钟时间到,大老板main叫停,活动结束");
myResource.stop();
}