生产者、消费者模型的demo:
1.程序入口:
package thread.test01;
public class ThreadCommunication {
public static void main(String[] args) {
Queue q = new Queue();
new Thread(new Producer(q)).start();
new Thread(new Consumer(q)).start();
}
}
2.共享数据列表:
package thread.test01;
public class Queue {
String name = "unknown";
String sex = "unknown";
boolean bFull = false;
}
3.生产者:
package thread.test01;
public class Producer implements Runnable {
private Queue q;
public Producer(Queue q) {
this.q = q;
}
@Override
public void run() {
int i = 0;
while (true) {
synchronized (q) {// 当前线程得到对象q的lock旗标
if (q.bFull) {
try {
q.wait();// 此时当前线程被放置在对象q的等待池中,当前线程释放q的锁旗标
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i == 0) {
q.name = "zhangsan";
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
q.sex = "male";
} else {
q.name = "wangwu";
q.sex = "female";
}
q.bFull = true;
q.notify();// 当另外的线程执行了对象o的notify()方法后,当前线程可能会被从q的等待
// 线程池中释放出来,并且移动到等待线程对象q的锁旗标的线程池中,当当前
//线程得到的锁旗标时就会执行下去
}
i = (i + 1) % 2;
}
}
}
4.消费者:
package thread.test01;
public class Consumer implements Runnable {
private Queue q;
public Consumer(Queue q) {
this.q = q;
}
@Override
public void run() {
while (true) {
synchronized (q) {
if (!q.bFull) {
try {
q.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(q.name);
System.out.println(":" + q.sex);
q.name = "unknown";
q.sex = "unknown";
q.bFull = false;
q.notify();
}
}
}
}
理解监视器对象、synchronized、wait、notify之间的关系是根本。
根据oop的设计,重构以上代码:
//
package thread.test02;
public class Queue {
private String name = "unknown";
private String sex = "unknown";
private boolean bFull = false;
public synchronized void put(String name, String sex) {
if (bFull) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.sex = sex;
bFull = true;
this.notifyAll();
}
public synchronized void get() {
if (!bFull) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+":"+sex);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
bFull = false;
this.notifyAll();
}
}
//
package thread.test02;
public class Producer implements Runnable {
private Queue q;
public Producer(Queue q) {
this.q = q;
}
@Override
public void run() {
int i = 0;
while (true) {
if (i == 0) {
q.put("zhangsan", "male");
} else {
q.put("wangwu", "female");
}
i = (i + 1) % 2;
}
}
}
//
package thread.test02;
public class Consumer implements Runnable {
private Queue q;
public Consumer(Queue q) {
this.q = q;
}
@Override
public void run() {
while (true) {
q.get();
}
}
}