生产者示例(线程资源共享,同步代码块,wait()notify()生产者问题)

1.第一步,首先让两个线程实现资源共享

2.第二步,解决线程并发问题

3.解决生产者和消费者依次进行的问题

volatile 修饰的属性为线程可见性属性

总结:锁代码块最好放在while里面,不然当一个线程一次获得了属性,就会将while循环执行完毕,所以同步代码块最好就只包括一次运行就结束的代码

代码:

public class Product {
//把三个类都放入一个一个公共类类中

//用静态方法修饰一个产品类,因为产品是公共操作对象
static class ProductObject{
//同时用静态修饰属性,可以使用类名调出属性
volatile static String str;
}

//创建生产者线程

static class Producttor extends Thread{

//创建一个对象,用来做锁的钥匙
Object projectObject;
//给
对象一个构造方法 ,到时候 创建线时将同一个对象传进来,这样就让两个房间的锁为同一把
public Producttor(Object object) {
super();
this.projectObject = object;
}
public void run() {
//首先进行循环,生产
while (true) {
//用锁把生产代码块锁起来,让他不跟消费代码同步执行
synchronized(projectObject){
// 进行生产前先判断产品是否存在
if ( ProductObject.str!=null) {
try {
// 如果产品存在就停止生产, 调用wait()释放线程资源,等待产品被消费后被唤醒
projectObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//假如没有产品就不会进入上面的判断,直接执行到这一步了,把当前时间转化为String类型的字符串给productObject的str赋值
ProductObject.str = System.currentTimeMillis()+"";

//同时输出生产者正在生产
System.out.println("生产者"+ProductObject.str);
//同时唤醒因为没有产品而被暂停的消费者线程
projectObject.notify();
}
}
}
}

//创建 消费者类
static class coumetur extends Thread{
//创建一个对象,用来做锁的钥匙
Object projectObject;
//给对象一个构造方法,到时候创建线时将同一个对象传进来,这样就让两个房间的锁为同一把
public coumetur(Object projectObject) {
super();
this.projectObject = projectObject;
}


public void run() {
//首先进行循环,消费
while(true){
//用锁把消费代码块锁起来,让他不跟生产代码同步执行
synchronized(projectObject){

//判断是否有产品
if ( ProductObject.str==null) {
try {
//假如没有产品,就停止消费
projectObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打印产品内容
System.out.println("消费者"+ProductObject.str);
//消费过后产品就不存在了,将参数初始化
ProductObject.str=null;
//唤醒生产者线程可以生产了
projectObject.notify();
}
}
}

//创建测试启动类
public static void main(String[] args) {
//创建一个新的对象,用来做为钥匙
Object object = new Object();

// 创建线程的时候将钥匙传进去 ,让 不同线程只能同时开其中一把锁 ,就不会引起线程并发安全性的问题
new Producttor(object).start();
new coumetur(object).start();

}
}

猜你喜欢

转载自blog.csdn.net/jinqianwang/article/details/80282966