synchronized同步程式+生產者消費者模式(訊號燈)解除可能出現的資源問題

wangdongli_1993發表於2018-07-09

多個同步可能會造成資源不正確或者造成死鎖  解決辦法有生產者消費者模式的訊號燈法

*synchronized同步  指的是多個程式訪問同一個資源,為了確保資源的正確性,進行同步

package xidian.lili.threadpro;
/**
 * 

 * 共同的資源是moive
 * 訪問這個資源的兩個執行緒是Player(生產者)和Wathcher(消費者)
 * wait()釋放鎖  區別於sleep(long time)
 * notify() 喚醒程式  必須和synchronized配合使用

 */
public class Movie {
private String pic;
private boolean flag=true;//一定要初始化  先要生產  才能消費

/**
* 訊號燈
* flag true 生產者生產 消費者等待 生產完畢 通知消費 生產者停下
* flag false 消費者消費 生產者等待  消費完畢 通知生產 消費者停下
*/

public Movie(){

}
//播放
public synchronized void play(String pic){
if(!flag){//生產者等待
try {
this.wait();
} catch (InterruptedException e) {

e.printStackTrace();
}
}
//開始生產
try {
Thread.sleep(100);
} catch (InterruptedException e) {

e.printStackTrace();
}
//生產完畢
this.pic=pic;
System.out.println("生產了"+pic);
//通知消費
this.notify();
//生產者停下
this.flag=false;

}
//觀看
public synchronized void watch(){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {

e.printStackTrace();
}
}
//開始消費
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//消費完成
System.out.println("消費了"+pic);
//通知生產
this.notify();
//停止消費
this.flag=true;
}
}

package xidian.lili.threadpro;

//生產者

public class Player  implements Runnable{
private Movie movie;
public Player(Movie m){
this.movie=m;
}
@Override
public void run() {
for(int i=0;i<20;i++){
if(i%2==0)
{
movie.play("你好嗎");
}
else{
movie.play("我很好");
}
}
}
}

package xidian.lili.threadpro;

//消費者

public class Watcher implements Runnable {
private Movie movie;
public Watcher(Movie m){
this.movie=m;
}
@Override
public void run() {
for(int i=0;i<20;i++){
movie.watch();
}
}

}

package xidian.lili.threadpro;

//主程式  應用

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();
}
}

相關文章