Java 中的等待唤醒机制

* 生产者消费者模式:
 *         
 *     Student类:     
 *             公共的字段:姓名和年龄(学生数据)
 *  SetThread类:生产者线程
 *          产生学生数据
 *  GetThread类:消费者线程
 *             消费学生数据
 * 
 * 
 *     StudentDemo类:主线程(用户线程): 开启生产者线程和消费者线程!
 * 
 * 问题1:消费者所在的线程和生产者所在的线程操作不是同一个资源对象
 *             null---0
 * 
 * 
 * 
 * 在刚才基础上优化:t1线程:不断产生数据,t2(消费者线程)不断消费数据
 * 在SetThread以及GetThread加入while循环
 * 
 * 
 * 问题2:
 *         1)同一个打印多次
 *         线程在执行的,抢占CPU执行权,如果抢占到CPU的执行权,
 *                 CPU一点点时间片可以让该I线程执行多次
 *         2)发现姓名和年龄不符
 *             线程的执行具有随机性
 * 
 *   针对刚才这个程序,解决线程安全问题:
 *   
 *   检验线程安全问题的标准是什么?
 *    1)是否为多线程环境
 *    2)是否有共享数据
 *    3)是否有多条对共享数据操作
 *    
 *    使用同步机制:synchronized同步代码块解决3)
 *            将多条语句对共享数据的操作包裹起来!
 *    
 *  继续优化:现在想让这个数据依次打印,而不是打印一片数据
 *              "hello",24
 *              "world",39
 *              ..
 *              ..
 *  
 *  引入Java中等待唤醒机制!
 *  
 *  生产者线程:判断是否有数据,没有数据,等待产生数据
 *  消费者线程:判断是否有数据,如果有数据,等待消费掉
 *  
 *  问题:产生死锁!
 *  生产者线程,产生数据了,等待消费数据
 *  消费者线程,消费完数据,等待生产数据
 *  
 *  
 *  
 *  
 *  面试题:
 *          1)sleep()和wait()方法的区别 
 *          
 *  区别1): 来源不同    
 *          sleep()是Thread类中方法
 *          wait()是Object类中方法:需要使用锁对象调用的
 *  
 *      2) 调用方法的时候是否释放锁
 *          sleep(long millis):线程睡眠多少毫秒数据(期间,线程是暂停状态)
 *          wait():线程等待,调用该方法,会立即释放锁对象!利用wait方法会释放锁对象,
 *              然后使用锁对象调用notify(),来完成Java中等待唤醒机制!
 *  
 *      3)共同点:wait和方法sleep()都会可能出现中断异常! InterruptedException
 *          
 *  
 *  
 *      2)wait()和notify()这些方法为什么不定义Thread类中,而是在Object类中呢?

public class StudentDemo {
			
	public static void main(String[] args) {
		
		//同一个学生资源对象
		Student s = new Student() ;
		
		//创建生产者资源类对象以及消费资源类对象
		SetThread st = new SetThread(s) ;
		GetThread gt = new GetThread(s) ;
		
		//创建线程类对象
		Thread t1 = new Thread(st) ;
		Thread t2 = new Thread(gt) ;
		
		t1.start();
		t2.start();
	}
}
//生产者资源类
/*
 * 
 * 
 * */
public class SetThread implements Runnable {
	
	//声明一个学生遍历
	private Student s ;
	public SetThread(Student s) {
		this.s = s ;
	}
	
	//定义一个统计变量
	private int x = 0 ;
	
	@Override
	public void run() {
		//t1线程(生产者线程)
		while(true) {
			//同步代码块
			synchronized(s) {
				if(s.flag) {
					//如果没有数据,
					//等待产生数据
					try {
						s.wait(); //立即释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				if(x % 2== 0) {  //x= 0
					s.name = "柯发兴" ;
					s.age = 24 ;
				}else {		//x = 1
					s.name = "高圆圆" ;
					s.age = 39 ; 
				}
				x ++;
				
				//修饰标记:
				s.flag = true ;//有数据了
				//通知对方线程消费数据
				s.notify();
				
			}
			
			
		}
		
		//产生学生对象,生产数据
//		Student s = new Student() ;
		
	}

}

public class Student {
	String name;
	int age;
    boolean flag ;//判断学生存在数据,默认false,不存在;true表示存在数据
}
//消费者资源类
public class GetThread implements Runnable {
	
	//成员变量
	private Student s ;
	public GetThread(Student s) {
		this.s = s ;
	}
	
	@Override
	public void run() {
		
		//不断消费数据
		while(true) {
			
			synchronized(s) {
				//消费者判断如果有数据,先消费掉
				if(!s.flag) {
					try {
						s.wait();//调用wati()会立即释放锁
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(s.name+"---"+s.age) ;
				
				
				//修饰标记:
				s.flag = false ;//没有数据类
				//通知生产线程产生数据
				s.notify();
			}
			
			
			
			
		}
	
		
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值