当多个线程并发访问同一个资源时,可使用生产者-消费者模式解决,通常有信号灯法和管程法,本文使用信号灯法实现,其基本思想为:生产者生产时,消费者等待,生产结束后通知消费者消费;消费者消费时,生产者等待,消费完后通知生产者生产。需要Object类中wait()方法和notify()或者notifyall()方法配合使用。
其中,wait()方法使得当前线程等待,直到另一个线程调用该对象的notify()或者notifyall()方法,wait()方法会释放锁资源(sleep 不释放锁);notify()或者 notifyall()方法唤醒等待的线程 ;wait()、 notify()必须和synchronized一起使用。
实例代码如下:flag为true--->生产者生产(play()方法) 消费者等待,生产完成后通知消费者; flag为false--->消费者消费(watch()方法) 生产者等待,消费完后通知生产者
public class Movie {
private String pic; //产品
//信号灯
private boolean flag = true;
//播放
public synchronized void play(String pic) {
if(!flag) { //生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开始生产
try {
Thread.sleep(500); //生产500ms
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产完毕 出来产品
System.out.println("生产:"+pic);
this.pic = pic;
//通知消费
this.notify();
//生产者停下
this.flag = false;
}
public synchronized void watch() {
if(flag) { //消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(200); //消费200ms
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费:"+pic);
//消费完毕
this.notifyAll();
//消费者停下
this.flag = true;
}
}
class Player implements Runnable{
private Movie m;
public Player(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for(int i=0;i<20;++i) {
if(0==i%2) {
m.play("蓝猫");
}else
{
m.play("淘气");
}
}
}
}
class Watcher implements Runnable{
private Movie m;
public Watcher(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for(int i=0;i<20;++i) {
m.watch();
}
}
}
public class App {
public static void main(String[] args) {
//共同的资源
Movie m = new Movie();
//多线程
Player p = new Player(m);
Watcher w = new Watcher(m);
new Thread(p).start();
new Thread(w).start();
}
}
13万+



被折叠的 条评论
为什么被折叠?



