??Object類的方法:等待wait() , 喚醒隊首線程notify() , 喚醒全部等待線程notifyAll()。利用等待和喚醒實現(xiàn)Producer線程、Consumer線程的互斥訪問Message對象。
代碼如下:
package ThreadDemo;
class Message {
private String msg = "";
private boolean flag = true; //記錄型信號量,規(guī)定true表示沒有消息(允許生產(chǎn)、不許消費),false表示已有消息(不許生產(chǎn)、允許消費)
public synchronized void setMessage(String msg) {
if(flag==false) {
try {
super.wait(); //不許生產(chǎn)、讓Producer線程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.msg=msg;
flag = false; //生產(chǎn)完成,改變信號量、喚醒Consumer
super.notify();
}
public synchronized String getMessage() {
if(flag==true) {
try {
super.wait(); //不許消費、讓Consumer線程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
return "msg = "+this.msg;
}
finally { //return后用finally確保指令執(zhí)行
flag = true; //消費完成,改變信號量、喚醒Producer
super.notify();
}
}
}
class Producer implements Runnable{
private Message msg;
public Producer(Message msg) {
this.msg = msg;
}
@Override
public void run() {
for(int x=0;x<30;x++) {
if(x%2==0) {
msg.setMessage("夏天,穿短袖短褲");
}
else {
msg.setMessage("冬天,換秋衣秋褲");
}
}
}
}
class Consumer implements Runnable{
private Message msg;
public Consumer(Message msg) {
this.msg = msg;
}
@Override
public void run() {
for(int x=0;x<30;x++) {
System.out.println(msg.getMessage());
}
}
}
public class Main {
public static void main(String[] args){
Message msg = new Message();
new Thread(new Producer(msg)).start(); //啟動生產(chǎn)者線程
new Thread(new Consumer(msg)).start(); //啟動消費者線程
}
}