使用到的方法和关键字
synchronized关键字:可以使线程一个个的执行
wait方法:使线程休眠,直到被唤醒才能执行
notifyAll方法:唤醒休眠的所有线程
Thread.sleep()方法:设置延迟时间,延迟一段时间再执行下面的代码
其他一些更为普遍的不再赘述。
问题描述
现在要求设置两个线程,一个生产者线程,一个消费者线程,当产品存货量等于0时不再进行消费等待唤醒,当产品存货量大于5时,不再进行生产等待唤醒,这个问题与其他问题的不同点在于,他的两个线程操作是不一样的。
出现的问题
首先也是最重要的是理解问题,要明白生产线程和消费线程是对同一个对象进行操作,不然没有任何意义,这样我们就需要再创建一个类存储公用的信息。
其次还有两个严重的问题。
第一,同步问题,如果不同步可能出现数据相同的状况。
第二,重复问题,不断重复生产线程数值会超过5,反之亦然,违背题目要求。
解决问题——思路
对于同步问题,我们采用synchronized同步代码块或者synchronized同步方法解决。对于重复问题,这里我们要借助存储公用信息的类,对它里面的不同方法进行休眠,用到了两个Object类中的wait和notify方法。
代码实现
//存储公用信息
class Message{
private String proname;
private int number;
public Message(String proname,int number) {
this.proname = proname;
this.number = number;
}
public synchronized void product() {
if(this.number>5) {
try {
super.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("生产"+this.proname+",存量:"+this.number++);
super.notifyAll();
}
public synchronized void consume() {
if(this.number==0) {
try {
super.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消耗"+this.proname+",存量:"+this.number--);
super.notifyAll();
}
}
//实现生产者线程
class Producer implements Runnable{
private Message mge;
public Producer(Message mge) {
this.mge = mge;
}
public void run() {
for(int i=0;i<9;i++) {
this.mge.product();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//实现消费者线程
class Consumer implements Runnable{
private Message mge;
public Consumer(Message mge) {
this.mge = mge;
}
public void run() {
for(int i=0;i<9;i++)
{
this.mge.consume();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Demo6 {
public static void main(String[] args) {
Message mge = new Message("甜品",8);
new Thread(new Producer(mge)).start();
new Thread(new Consumer(mge)).start();
}
}